ofa_main

OnField Assistant (ofa) — locally hosted, RAG-augmented LLM for HPC and scientific-computing workflows.

Functions

chat_complete(messages)

Non-streaming chat call — returns full response string (for planning).

chat_stream(messages, **option_overrides)

Stream a chat response from Ollama using per-model sampling options.

check_and_execute_bash(response_text)

Parse the assistant's response for tool-use fences and dispatch each tool's handler.

ensure_ollama_running()

Start Ollama server if not already running.

extract_and_save_lessons(response_text)

Persist a `=== LESSON === .

extract_and_save_prefs(response_text)

Persist a `=== PREFS === .

extract_plan(response_text)

fetch_url_context(query[, max_chars])

Extract URLs from query, fetch their content, and return as context.

generate_file(filepath, query, rag_context, ...)

Generate a single OpenFOAM file, using already-generated files as context.

get_model_options()

Return the sampling options for the currently-selected MODEL.

get_model_thought_tags()

Native chat-template thinking tags for the currently-selected MODEL, used by make_thought_filter() to also hide upstream reasoning streams on top of our own <thought>...</thought> convention.

handle_slurm_sigterm(*args)

hpc_single_query(query[, resume, code_mode, ...])

interactive_mode([save_dir, resume, ...])

Run interactive chat loop.

load_session()

load_system_prompt([prompt_type])

main()

make_thought_filter([extra_tag_pairs])

Build a streaming filter that hides 'thinking' regions from display.

manage_session_context(messages[, max_chars])

Compress session history to stay within max_chars budget.

model_supports_vision([model])

True if the given model id (default: active MODEL) can accept images.

plan_file_list(query, rag_context, system_prompt)

Ask the LLM to plan which files the case needs, in generation order.

retrieve_amrex_context(query[, top_k])

AMReX-only retrieval.

retrieve_context(query[, top_k])

Retrieve relevant OpenFOAM file chunks from the vector database using Hybrid Search.

retrieve_hpc_context(query[, top_k])

retrieve_marbles_context(query[, top_k])

MARBLES-focused retrieval.

retrieve_private_context(query[, top_k])

Retrieve from the user's own indexed data, if any.

retrieve_quantum_computing_context(query[, ...])

Quantum-computing focused retrieval.

retrieve_vasp_context(query[, top_k])

VASP-focused retrieval.

save_case(response_text, output_dir)

Parse response and save files to a case directory.

save_session(messages)

single_query(query[, save_dir, fast, resume])

ofa_main.model_supports_vision(model=None)[source]

True if the given model id (default: active MODEL) can accept images.

Parameters:

model (str | None)

Return type:

bool

ofa_main.get_model_options()[source]

Return the sampling options for the currently-selected MODEL.

Per-env-var overrides ($OFA_TEMPERATURE etc.) always win over the registry, so a one-off tweak doesn’t require editing the registry.

ofa_main.get_model_thought_tags()[source]

Native chat-template thinking tags for the currently-selected MODEL, used by make_thought_filter() to also hide upstream reasoning streams on top of our own <thought>…</thought> convention.

ofa_main.save_session(messages)[source]
ofa_main.load_session()[source]
ofa_main.manage_session_context(messages, max_chars=100000)[source]

Compress session history to stay within max_chars budget.

Strategy (oldest → newest, skipping system prompt and the last 2 messages so the model retains the immediate user→assistant→tool context):

  1. Drop <thought>...</thought> deliberation from old assistant turns.

  2. Replace old "Output from executed commands:" user messages with a short placeholder.

  3. Strip the contents of fenced code blocks (` ... `) from any other old user message above LARGE_USER_MSG_CHARS — this catches large @file pastes and command outputs the model produced from sources other than the tool-execution helper.

We only emit the “Compressing…” banner when we actually freed bytes, and we now report before→after sizes so the user can see the effect. If we still cannot reach the target after exhausting eligible messages, we hint at /clear instead of repeatedly alarming the user on every subsequent turn.

ofa_main.make_thought_filter(extra_tag_pairs=None)[source]

Build a streaming filter that hides ‘thinking’ regions from display.

Always hides our own <thought>…</thought> convention. Additionally hides any (open_tag, close_tag) pairs in extra_tag_pairs, which the caller typically gets from get_model_thought_tags() — used for models whose chat template emits a native reasoning channel that should not be shown to the end user.

The captured response string fed back to the caller stays intact, so the model retains continuity with its own scratchpad on the next turn.

ofa_main.extract_and_save_prefs(response_text)[source]

Persist a === PREFS === … === END PREFS === block from the model.

Parameters:

response_text (str)

ofa_main.extract_and_save_lessons(response_text)[source]

Persist a === LESSON === … === END LESSON === block from the model.

Triggered autonomously when the model recognizes a failure mode, an environment quirk, or a user correction. The ‘Lessons Channel’ system prompt encourages this without requiring an explicit user directive. Capped tighter than prefs (2/turn vs 4) to prevent the model from spamming the lessons file with every observation.

Parameters:

response_text (str)

ofa_main.extract_plan(response_text)[source]
Parameters:

response_text (str)

ofa_main.load_system_prompt(prompt_type='openfoam')[source]
ofa_main.ensure_ollama_running()[source]

Start Ollama server if not already running.

The chosen TCP port is persisted to <OFA_SCRATCH>/.ofa_ollama.port and the daemon’s PID to <OFA_SCRATCH>/.ofa_ollama.pid. Concurrent ofa invocations by the same user reuse the same daemon when possible.

ofa_main.fetch_url_context(query, max_chars=64000)[source]

Extract URLs from query, fetch their content, and return as context.

Parameters:
Return type:

str

ofa_main.retrieve_context(query, top_k=10)[source]

Retrieve relevant OpenFOAM file chunks from the vector database using Hybrid Search.

Parameters:
Return type:

str

ofa_main.chat_stream(messages, **option_overrides)[source]

Stream a chat response from Ollama using per-model sampling options.

Parameters:

messages (list)

ofa_main.chat_complete(messages)[source]

Non-streaming chat call — returns full response string (for planning).

Parameters:

messages (list)

Return type:

str

ofa_main.plan_file_list(query, rag_context, system_prompt)[source]

Ask the LLM to plan which files the case needs, in generation order.

Returns a list of file paths (e.g. [“system/controlDict”, “0/U”, …]) or None if parsing fails (caller should fall back to single-shot).

Parameters:
  • query (str)

  • rag_context (str)

  • system_prompt (str)

Return type:

list[str] | None

ofa_main.generate_file(filepath, query, rag_context, system_prompt, generated)[source]

Generate a single OpenFOAM file, using already-generated files as context.

Streams output to stdout and returns the full file content.

Parameters:
Return type:

str

ofa_main.save_case(response_text, output_dir)[source]

Parse response and save files to a case directory.

Parameters:
  • response_text (str)

  • output_dir (str)

ofa_main.interactive_mode(save_dir=None, resume=False, hpc_mode=False, code_mode=False, amrex_mode=False, marbles_mode=False, reframe_mode=False, quantum_computing_mode=False, vasp_mode=False)[source]

Run interactive chat loop.

Parameters:
ofa_main.single_query(query, save_dir=None, fast=False, resume=False)[source]
Parameters:
ofa_main.retrieve_amrex_context(query, top_k=5)[source]

AMReX-only retrieval. Grabs top-k results from amrex_src plus a small slice of hpc_docs (module paths / SLURM) so the model has Kestrel context for a real build/run. Does NOT touch marbles_src — use retrieve_marbles_context() for that mode.

Parameters:
Return type:

str

ofa_main.retrieve_marbles_context(query, top_k=5)[source]

MARBLES-focused retrieval.

Queries marbles_src primarily (top-k), with a smaller amrex_src slice (top-2) because MARBLES is a lattice-Boltzmann solver built on top of AMReX — its users legitimately need to trace into MultiFab / ParallelFor / BoxArray details for anything non-trivial. Also grabs light HPC docs for module paths / SLURM.

Split introduced when the old combined –amrex mode was factored into pure –amrex and –marbles modes; keeping the AMReX slice in the marbles path preserves the useful behaviour of the old mode for LBM developers.

Parameters:
Return type:

str

ofa_main.retrieve_quantum_computing_context(query, top_k=7)[source]

Quantum-computing focused retrieval.

Queries the single quantum_computing collection, which mixes code (Qiskit / Cirq / PennyLane / cuQuantum snippets) with PDFs (papers, thesis excerpts, textbook chapters). Metadata source_type distinguishes them; retrieval headers surface that plus (for PDFs) the page number so the model can cite properly.

Also grabs a light HPC docs slice so module load / Slurm advice is grounded when users ask about running quantum simulators on Kestrel.

Parameters:
Return type:

str

ofa_main.retrieve_private_context(query, top_k=5)[source]

Retrieve from the user’s own indexed data, if any.

Returns “” when the user has no private store, which is the common case — callers can append the result unconditionally. Searches every private collection and interleaves the results, since a user’s corpora are usually small and topically distinct enough that ranking across them is not worth the complexity.

Parameters:
Return type:

str

ofa_main.retrieve_vasp_context(query, top_k=5)[source]

VASP-focused retrieval.

Queries the vasp_src collection (tutorials + general notes + Wisconsin docs snapshot), pins Applications/vasp.md from the HPC docs as the authoritative build / module / Slurm / licensing reference, and adds a small hpc_docs slice so tooling advice stays grounded when users ask about running VASP on Kestrel.

Parameters:
Return type:

str

ofa_main.retrieve_hpc_context(query, top_k=15)[source]
Parameters:
Return type:

str

ofa_main.check_and_execute_bash(response_text)[source]

Parse the assistant’s response for tool-use fences and dispatch each tool’s handler. Returns the concatenated tool output (for feeding back into the LLM as a new user message), or None if nothing was executed.

ofa_main.hpc_single_query(query, resume=False, code_mode=False, amrex_mode=False, marbles_mode=False, reframe_mode=False, quantum_computing_mode=False, vasp_mode=False)[source]
Parameters:
ofa_main.handle_slurm_sigterm(*args)[source]
ofa_main.main()[source]