harn-stdlib 0.8.0

Embedded Harn standard library source catalog
Documentation
fn __workflow_non_empty_string(value) {
  if type_of(value) != "string" {
    return nil
  }
  let trimmed = trim(value)
  if trimmed == "" {
    return nil
  }
  return trimmed
}

fn __workflow_stage_tool_format(model_policy, host) {
  let explicit = __workflow_non_empty_string(model_policy?.tool_format)
  if explicit != nil {
    return explicit
  }
  let env = __workflow_non_empty_string(host?.env_tool_format)
  if env != nil {
    return env
  }
  let default_format = __workflow_non_empty_string(host?.default_tool_format)
  if default_format != nil {
    return default_format
  }
  return "text"
}

fn __workflow_native_tool_fallback(value) {
  let policy = __workflow_non_empty_string(value)
  if policy != nil {
    return policy
  }
  return "reject"
}

fn __workflow_autonomy_tier(value) {
  let tier = value ?? "act_auto"
  if tier == "shadow" || tier == "suggest" || tier == "act_with_approval" || tier == "act_auto" {
    return tier
  }
  throw "workflow_autonomy_policy: tier must be one of shadow, suggest, act_with_approval, act_auto"
}

/** workflow_autonomy_policy normalizes tier policy for with_autonomy_policy. */
pub fn workflow_autonomy_policy(config = nil) {
  let cfg = config ?? {}
  return {
    agent_id: cfg?.agent_id ?? cfg?.agent,
    autonomy_tier: __workflow_autonomy_tier(cfg?.autonomy_tier ?? cfg?.tier),
    action_tiers: cfg?.action_tiers ?? {},
    agent_tiers: cfg?.agent_tiers ?? {},
    agent_action_tiers: cfg?.agent_action_tiers ?? {},
    reviewers: cfg?.reviewers ?? [],
  }
}

fn __workflow_add_model_option(options, model_policy, key) {
  let value = model_policy[key]
  if value == nil {
    return options
  }
  return options + {[key]: value}
}

fn __workflow_llm_options(config, model_policy, tool_format) {
  var options = {tool_format: tool_format}
  if __workflow_non_empty_string(config?.session_id) != nil {
    options = options + {session_id: __workflow_non_empty_string(config?.session_id)}
  }
  options = __workflow_add_model_option(options, model_policy, "provider")
  options = __workflow_add_model_option(options, model_policy, "model")
  options = __workflow_add_model_option(options, model_policy, "model_tier")
  options = __workflow_add_model_option(options, model_policy, "temperature")
  options = __workflow_add_model_option(options, model_policy, "max_tokens")
  return options
}

fn __workflow_add_loop_option(options, model_policy, key) {
  let value = model_policy[key]
  if value == nil {
    return options
  }
  return options + {[key]: value}
}

fn __workflow_agent_loop_options(config, model_policy, tool_format) {
  var options = {
    loop_until_done: true,
    max_iterations: model_policy?.max_iterations ?? 16,
    max_nudges: model_policy?.max_nudges ?? 3,
    tool_retries: 0,
    tool_backoff_ms: 1000,
    schema_retries: 0,
    tool_format: tool_format,
    native_tool_fallback: __workflow_native_tool_fallback(model_policy?.native_tool_fallback),
    daemon: false,
    llm_retries: 2,
    llm_backoff_ms: 2000,
    exit_when_verified: config?.exit_when_verified ?? false,
    loop_detect_warn: 2,
    loop_detect_block: 3,
    loop_detect_skip: 4,
  }
  if __workflow_non_empty_string(config?.session_id) != nil {
    options = options + {session_id: __workflow_non_empty_string(config?.session_id)}
  }
  if config?.done_sentinel != nil {
    options = options + {done_sentinel: config?.done_sentinel}
  }
  options = __workflow_add_loop_option(options, model_policy, "nudge")
  options = __workflow_add_loop_option(options, model_policy, "tool_examples")
  options = __workflow_add_loop_option(options, model_policy, "turn_policy")
  options = __workflow_add_loop_option(options, model_policy, "stop_after_successful_tools")
  options = __workflow_add_loop_option(options, model_policy, "require_successful_tools")
  return options
}

/** workflow_stage_agent_options. */
pub fn workflow_stage_agent_options(config = nil) {
  let cfg = config ?? {}
  let model_policy = cfg?.model_policy ?? {}
  let host = cfg?.host ?? {}
  let tool_format = __workflow_stage_tool_format(model_policy, host)
  let llm_options = __workflow_llm_options(cfg, model_policy, tool_format)
  let loop_options = __workflow_agent_loop_options(cfg, model_policy, tool_format)
  return {
    run_agent_loop: cfg?.mode == "agent" || cfg?.has_tools,
    tool_format: tool_format,
    llm_options: llm_options,
    agent_loop_options: llm_options + loop_options,
  }
}