harn-stdlib 0.8.10

Embedded Harn standard library source catalog
Documentation
fn __workflow_list(value) {
  if type_of(value) == "list" {
    return value
  }
  return []
}

fn __workflow_contains(values, value) {
  return contains(__workflow_list(values), value)
}

fn __workflow_num(value, fallback = 0) {
  if type_of(value) == "int" || type_of(value) == "float" {
    return value
  }
  return fallback
}

fn __workflow_freshness_rank(value) {
  if value == "stale" {
    return 0
  }
  if value == "normal" || value == nil {
    return 1
  }
  if value == "fresh" {
    return 2
  }
  if value == "live" {
    return 3
  }
  return 1
}

fn __workflow_metadata_string_list(artifact, key) {
  let metadata = artifact?.metadata ?? {}
  let raw = metadata[key]
  var out = []
  for item in __workflow_list(raw) {
    if type_of(item) == "string" && trim(item) != "" {
      out = out.push(trim(item))
    }
  }
  return out
}

fn __workflow_push_unique(values, value) {
  if __workflow_contains(values, value) {
    return values
  }
  return values.push(value)
}

fn __workflow_fresh_changed_paths(artifacts) {
  var paths = []
  for artifact in artifacts {
    if __workflow_freshness_rank(artifact?.freshness) >= 2 {
      for path in __workflow_metadata_string_list(artifact, "changed_paths") {
        paths = __workflow_push_unique(paths, path)
      }
    }
  }
  return paths
}

fn __workflow_artifact_has_stale_evidence(artifact, fresh_changed_paths) {
  let evidence_paths = __workflow_metadata_string_list(artifact, "evidence_paths")
  if len(evidence_paths) == 0 {
    return false
  }
  if __workflow_freshness_rank(artifact?.freshness) >= 2 {
    return false
  }
  for path in evidence_paths {
    if __workflow_contains(fresh_changed_paths, path) {
      return true
    }
  }
  return false
}

fn __workflow_drop_stale_evidence_artifacts(artifacts) {
  let fresh_changed_paths = __workflow_fresh_changed_paths(artifacts)
  if len(fresh_changed_paths) == 0 {
    return artifacts
  }
  var out = []
  for artifact in artifacts {
    if !__workflow_artifact_has_stale_evidence(artifact, fresh_changed_paths) {
      out = out.push(artifact)
    }
  }
  return out
}

fn __workflow_artifact_text(artifact) {
  if artifact?.text == nil {
    return ""
  }
  return artifact.text
}

fn __workflow_artifact_priority(artifact) {
  return __workflow_num(artifact?.priority, 0)
}

fn __workflow_dedup_artifacts(artifacts) {
  var out = []
  for artifact in artifacts {
    let text = __workflow_artifact_text(artifact)
    if text == "" {
      out = out.push(artifact)
      continue
    }
    var next = []
    var replaced = false
    for existing in out {
      if !replaced && __workflow_artifact_text(existing) == text {
        if __workflow_artifact_priority(artifact) > __workflow_artifact_priority(existing) {
          next = next.push(artifact)
        } else {
          next = next.push(existing)
        }
        replaced = true
      } else {
        next = next.push(existing)
      }
    }
    if !replaced {
      next = next.push(artifact)
    }
    out = next
  }
  return out
}

fn __workflow_microcompact_text(text, max_chars) {
  if len(text) <= max_chars || max_chars < 200 {
    return text
  }
  let keep = floor(max_chars / 2)
  let tail_start = max(len(text) - keep, 0)
  let head = text.substring(0, keep)
  let tail = text.substring(tail_start, len(text))
  let snipped = len(text) - len(head) - len(tail)
  return head + "\n\n[... " + to_string(snipped) + " characters snipped ...]\n\n" + tail
}

fn __workflow_microcompact_artifact(artifact, cap_tokens) {
  let estimated = __workflow_num(artifact?.estimated_tokens, 0)
  let max_chars = cap_tokens * 4
  if estimated <= cap_tokens * 2 || max_chars < 200 || artifact?.text == nil {
    return artifact
  }
  if len(artifact.text) <= max_chars {
    return artifact
  }
  return artifact
    + {text: __workflow_microcompact_text(artifact.text, max_chars), estimated_tokens: cap_tokens}
}

fn __workflow_microcompact_artifacts(artifacts, policy) {
  if policy?.max_tokens == nil || len(artifacts) == 0 {
    return artifacts
  }
  let count = max(len(artifacts), 1)
  let max_tokens = policy.max_tokens
  let per_artifact_budget = floor(max_tokens / count)
  let cap = min(max(per_artifact_budget, 500), max_tokens)
  var out = []
  for artifact in artifacts {
    out = out.push(__workflow_microcompact_artifact(artifact, cap))
  }
  return out
}

fn __workflow_artifact_matches_policy(artifact, policy) {
  let include_kinds = __workflow_list(policy?.include_kinds)
  let exclude_kinds = __workflow_list(policy?.exclude_kinds)
  let include_stages = __workflow_list(policy?.include_stages)
  if len(include_kinds) > 0 && !__workflow_contains(include_kinds, artifact?.kind) {
    return false
  }
  if __workflow_contains(exclude_kinds, artifact?.kind) {
    return false
  }
  if len(include_stages) > 0 && !__workflow_contains(include_stages, artifact?.stage) {
    return false
  }
  return true
}

fn __workflow_artifact_precedes(left, right, policy) {
  let pinned_ids = __workflow_list(policy?.pinned_ids)
  let left_pinned = __workflow_contains(pinned_ids, left?.id)
  let right_pinned = __workflow_contains(pinned_ids, right?.id)
  if left_pinned != right_pinned {
    return left_pinned
  }
  let prioritize_kinds = __workflow_list(policy?.prioritize_kinds)
  let left_kind = __workflow_contains(prioritize_kinds, left?.kind)
  let right_kind = __workflow_contains(prioritize_kinds, right?.kind)
  if left_kind != right_kind {
    return left_kind
  }
  let left_priority = __workflow_artifact_priority(left)
  let right_priority = __workflow_artifact_priority(right)
  if left_priority != right_priority {
    return left_priority > right_priority
  }
  if policy?.prefer_fresh {
    let left_fresh = __workflow_freshness_rank(left?.freshness)
    let right_fresh = __workflow_freshness_rank(right?.freshness)
    if left_fresh != right_fresh {
      return left_fresh > right_fresh
    }
  }
  if policy?.prefer_recent {
    let left_created = to_string(left?.created_at ?? "")
    let right_created = to_string(right?.created_at ?? "")
    if left_created != right_created {
      return left_created > right_created
    }
  }
  let left_relevance = __workflow_num(left?.relevance, 0)
  let right_relevance = __workflow_num(right?.relevance, 0)
  if left_relevance != right_relevance {
    return left_relevance > right_relevance
  }
  let left_tokens = __workflow_num(left?.estimated_tokens, 999999999)
  let right_tokens = __workflow_num(right?.estimated_tokens, 999999999)
  if left_tokens != right_tokens {
    return left_tokens < right_tokens
  }
  return false
}

fn __workflow_insert_artifact_sorted(sorted, artifact, policy) {
  var out = []
  var inserted = false
  for existing in sorted {
    if !inserted && __workflow_artifact_precedes(artifact, existing, policy) {
      out = out.push(artifact)
      inserted = true
    }
    out = out.push(existing)
  }
  if !inserted {
    out = out.push(artifact)
  }
  return out
}

fn __workflow_sort_artifacts(artifacts, policy) {
  var sorted = []
  for artifact in artifacts {
    sorted = __workflow_insert_artifact_sorted(sorted, artifact, policy)
  }
  return sorted
}

/** workflow_stage_context_policy. */
pub fn workflow_stage_context_policy(context_policy = nil, input_contract = nil) {
  let policy = context_policy ?? {}
  if len(__workflow_list(policy?.include_kinds)) > 0 {
    return policy
  }
  let input_kinds = __workflow_list(input_contract?.input_kinds)
  if len(input_kinds) == 0 {
    return policy
  }
  return policy + {include_kinds: input_kinds}
}

/** workflow_select_artifacts. */
pub fn workflow_select_artifacts(artifacts = nil, policy = nil) {
  let opts = policy ?? {}
  var candidates = []
  for artifact in __workflow_list(artifacts) {
    if __workflow_artifact_matches_policy(artifact, opts) {
      candidates = candidates.push(artifact)
    }
  }
  let sorted = __workflow_sort_artifacts(candidates, opts)
  let reserve_tokens = __workflow_num(opts?.reserve_tokens, 0)
  let max_tokens = if opts?.max_tokens == nil {
    nil
  } else {
    max(__workflow_num(opts.max_tokens, 0) - reserve_tokens, 0)
  }
  var used_tokens = 0
  var selected = []
  for artifact in sorted {
    if opts?.max_artifacts != nil && len(selected) >= opts.max_artifacts {
      break
    }
    let next_tokens = __workflow_num(artifact?.estimated_tokens, 0)
    if max_tokens != nil && used_tokens + next_tokens > max_tokens {
      continue
    }
    used_tokens = used_tokens + next_tokens
    selected = selected.push(artifact)
  }
  return selected
}

/** workflow_select_artifacts_adaptive. */
pub fn workflow_select_artifacts_adaptive(artifacts = nil, policy = nil) {
  let opts = policy ?? {}
  let fresh = __workflow_drop_stale_evidence_artifacts(__workflow_list(artifacts))
  let deduped = __workflow_dedup_artifacts(fresh)
  let compacted = __workflow_microcompact_artifacts(deduped, opts)
  return workflow_select_artifacts(compacted, opts)
}

/** workflow_select_stage_artifacts. */
pub fn workflow_select_stage_artifacts(config = nil) {
  let opts = config ?? {}
  let policy = workflow_stage_context_policy(opts?.context_policy ?? {}, opts?.input_contract ?? {})
  return {
    context_policy: policy,
    artifacts: workflow_select_artifacts_adaptive(opts?.artifacts ?? [], policy),
  }
}