harn-vm 0.7.0

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

/** clip_text. */
pub fn clip_text(text, max_chars) {
  if max_chars == nil || max_chars <= 0 {
    return text
  }
  if len(text) <= max_chars {
    return text
  }
  if max_chars <= 16 {
    return text.substring(0, max_chars)
  }
  return text.substring(0, max_chars - 15) + "\n...[truncated]"
}

/** render_section. */
pub fn render_section(section, include_headers, section_max_chars) {
  if section == nil || section?.enabled == false {
    return ""
  }
  let content = section?.content ?? ""
  if content == "" {
    return ""
  }
  let body = clip_text(content, section?.max_chars ?? section_max_chars)
  if include_headers == false || section?.name == nil || section?.name == "" {
    return body
  }
  return "[" + section?.name + "]\n" + body
}

/** context_section. */
pub fn context_section(name, content, options) {
  let opts = options ?? {}
  return filter_nil({
    _type: "context_section",
    name: name,
    content: content,
    kind: opts?.kind,
    path: opts?.path,
    priority: opts?.priority,
    max_chars: opts?.max_chars,
    enabled: opts?.enabled
  })
}

/** section. */
pub fn section(name, content, options) {
  return context_section(name, content, options)
}

/** context_attach. */
pub fn context_attach(name, path, content, options) {
  let opts = options ?? {}
  return context_section(name, "Path: " + path + "\n\n" + content, opts + {
    kind: opts?.kind ?? "attachment",
    path: path
  })
}

/** context. */
pub fn context(sections, options) {
  let opts = options ?? {}
  return filter_nil({
    _type: "context",
    sections: sections ?? [],
    separator: opts?.separator ?? "\n\n",
    include_headers: opts?.include_headers,
    max_chars: opts?.max_chars,
    section_max_chars: opts?.section_max_chars
  })
}

/** context_add. */
pub fn context_add(ctx, new_section) {
  let sections = (ctx?.sections ?? []) + [new_section]
  return context(sections, ctx)
}

/** context_render. */
pub fn context_render(ctx, options) {
  let opts = (ctx ?? {}) + (options ?? {})
  let separator = opts?.separator ?? "\n\n"
  let max_chars = opts?.max_chars
  let section_max_chars = opts?.section_max_chars
  let include_headers = opts?.include_headers != false

  var pieces = []
  var used = 0
  var section_text = ""
  var remaining = nil
  var clipped = ""
  for sec in opts?.sections ?? [] {
    section_text = render_section(sec, include_headers, section_max_chars)
    if section_text == "" {
      continue
    }
    remaining = if max_chars == nil { nil } else { max_chars - used }
    if remaining != nil && remaining <= 0 {
      break
    }
    clipped = clip_text(section_text, remaining)
    pieces = pieces + [clipped]
    used = used + len(clipped) + len(separator)
  }
  return join(pieces, separator)
}

/** context_compact. */
pub fn context_compact(ctx, options) {
  let opts = (ctx ?? {}) + (options ?? {})
  return context(opts?.sections ?? [], {
    separator: opts?.separator,
    include_headers: opts?.include_headers,
    max_chars: opts?.max_chars,
    section_max_chars: opts?.section_max_chars
  })
}

/** prompt_compose. */
pub fn prompt_compose(task, ctx, options) {
  let opts = options ?? {}
  let rendered = context_render(ctx, opts)
  let task_label = opts?.task_label ?? "Task"
  let prompt = "<workflow_task>\n<label>"
    + task_label
    + "</label>\n<instructions>\n"
    + task
    + "\n</instructions>\n</workflow_task>"
    + if rendered == "" {
      ""
    } else {
      "\n\n<workflow_context>\n" + rendered + "\n</workflow_context>"
    }
    + "\n\n<workflow_response_contract>\n"
    + "Respond to the workflow task above. Do not continue the trailing artifact text verbatim. Keep commentary minimal and use the active tool-calling contract for concrete progress.\n"
    + "</workflow_response_contract>"
  return filter_nil({
    prompt: prompt,
    system: opts?.system,
    rendered_context: rendered,
    context: ctx
  })
}