pycsamt.agents.context#

pycsamt.agents.context#

ContextInputAgent — Natural-language → pycsamt workflow config.

Accepts a free-text request such as:

"Load the EDI files in /data/WILLY_DATA/L22PLT, remove static shift,
 run phase tensor analysis for periods 1e-4 to 1 s, and save a report
 to /output/survey_report/"

and returns a validated AgentResult whose data["config"] is a structured dict the AgentCoordinator can execute directly.

When no LLM API key is available the agent falls back to a robust set of regex patterns that cover the most common request forms.

Classes

ContextInputAgent(*[, api_key, model, ...])

Parse a natural-language MT workflow request into a structured config.

class pycsamt.agents.context.ContextInputAgent(*, api_key=None, model=None, llm_provider='claude')[source]#

Bases: BaseAgent

Parse a natural-language MT workflow request into a structured config.

Parameters:
  • api_key (str or None) – LLM API key. When None the regex fallback is used exclusively.

  • model (str) – Passed to BaseAgent.

  • llm_provider (str) – Passed to BaseAgent.

Examples

With an API key:

agent = ContextInputAgent(api_key="sk-ant-…")
result = agent.execute({
    "request": "Load EDIs from /data/L22PLT, QC them, "
               "period range 1e-4 to 1 s, save to /out/qc/"
})
cfg = result["config"]
# cfg["workflow"]    == "qc"
# cfg["data_path"]   == "/data/L22PLT"
# cfg["period_range"] == [0.0001, 1.0]

Without an API key (regex fallback):

agent = ContextInputAgent()          # no key → regex mode
result = agent.execute({"request": "…"})
SYSTEM_PROMPT: str = 'You are an expert MT/AMT/CSAMT workflow configuration interpreter for pycsamt v2.\n\nGiven a natural-language processing request, extract a structured JSON configuration dictionary with the following schema (include only keys that are clearly mentioned or can be reasonably inferred):\n\n{\n  "workflow":       string one of:\n                    qc, static_shift, phase_analysis, forward,\n                    inversion_prep, pre_inversion, inversion_eval,\n                    interpretation, report, full,\n                    ai_inversion, inv1d, inv2d, inv3d,\n                    ensemble_inversion, joint_inversion,\n                    modem, mare2dem, occam2d,\n                    tipper, sensitivity, rotation,\n                    freq_decimation, batch, comparison,\n                    full_ai_workflow,\n  "data_path":      string absolute or relative path to EDI\n                    file(s) or directory,\n  "output_dir":     string where to write results / figures,\n  "period_range":   [T_min_seconds, T_max_seconds],\n  "component":      string "xy"|"yx"|"all"|"off_diagonal",\n  "station":        string or null,\n  "inversion_code": string "occam2d"|"modem"|"mare2dem"|null,\n  "depth_max_km":   float or null,\n  "n_periods":      int or null,\n  "verbose":        bool\n}\n\nRules:\n- Choose "ai_inversion" for CNN / 1-D neural-network / deep-learning\n  inversion requests.\n- Choose "inv2d" for U-Net / 2-D neural / profile AI inversion.\n- Choose "inv3d" for GCN / graph-convolutional / 3-D AI inversion.\n- Choose "ensemble_inversion" for ensemble / uncertainty / Bayesian.\n- Choose "joint_inversion" for joint / multi-modal / TEM+MT.\n- Choose "full_ai_workflow" when both AI inversion and full pipeline\n  are requested together.\n- If a period range is given in frequency (Hz), convert to period\n  (s = 1/f).\n- Preserve the full absolute path exactly as given.\n- Return ONLY the JSON object no markdown fences, no prose.\n'#

Override in subclasses to give the LLM its domain expertise.

execute(input_data)[source]#

Run this agent on input_data and return an AgentResult.

Subclasses must implement this method. The contract:

  • Reset self._last_cost = 0.0 at the top.

  • Record wall-clock time with t0 = time.time().

  • Return AgentResult(elapsed_seconds=time.time()-t0, cost_estimate_usd=self._last_cost, ...).

Parameters:

input_data (dict[str, Any])

Return type:

AgentResult