The session_helpers.py module#

Summary#

build_open_session_snippet

Snippet that opens a Lumerical session and prints metadata as JSON.

build_close_session_snippet

Snippet that closes a Lumerical session and prints the result as JSON.

build_eval_snippet

Snippet that runs LSF in a session and prints a small status JSON.

build_close_all_snippet

Snippet that closes every still-open Lumerical session (used at shutdown).

extract_json_payload

Pull the last JSON document printed to stdout, or None if absent.

envelope_success

Build a success envelope as a plain JSON-safe dictionary.

envelope_failure

Build a failure envelope as a plain JSON-safe dictionary.

render_envelope_from_execute

Convert a PersistentPythonSession.execute result to our envelope.

Description#

Pure helpers for building Python snippets and parsing subprocess results.

Every MCP tool in ansys.lumerical.mcp.tools follows the same shape:

  1. Build a short Python snippet (build_*_snippet()) that calls the helpers seeded into the persistent subprocess by ansys.lumerical.mcp.startup_code and prints a single JSON line on success.

  2. Run the snippet via PersistentPythonSession.execute(snippet).

  3. Wrap the framework’s result dictionary into one of the JSON envelopes (envelope_success(), envelope_failure()).

Keeping these functions pure makes the tool layer trivial to unit test without spawning a real subprocess or installing Lumerical.

Module detail#

session_helpers.build_open_session_snippet(name: str, product: str, filename: str | None, hide: bool) str#

Snippet that opens a Lumerical session and prints metadata as JSON.

session_helpers.build_close_session_snippet(name: str) str#

Snippet that closes a Lumerical session and prints the result as JSON.

session_helpers.build_eval_snippet(session: str, script: str) str#

Snippet that runs LSF in a session and prints a small status JSON.

Lumerical’s .eval() returns None. Outputs from the script (such as ?x;) go to the Lumerical log, not the Python subprocess stdout. If the agent needs values back, it should call getv/getresult via execute_python_code after this returns.

session_helpers.build_close_all_snippet() str#

Snippet that closes every still-open Lumerical session (used at shutdown).

session_helpers.extract_json_payload(stdout: str) Any | None#

Pull the last JSON document printed to stdout, or None if absent.

The startup-code helpers use _lum_print_json, which emits exactly one JSON document per call (single-line by default). Other libraries may have printed unrelated text before that, so this process is used:

  1. Try a whole-string parse first.

  2. Try a per-line parse from the end (cheap, single-line JSON).

  3. Fall back to scanning backwards through { / [ openers and using json.JSONDecoder.raw_decode to recover pretty-printed JSON that spans multiple lines.

session_helpers.envelope_success(payload: Any, **extras: Any) dict[str, Any]#

Build a success envelope as a plain JSON-safe dictionary.

Returning a dictionary (rather than a JSON string) lets FastMCP deliver the result as MCP structuredContent, so clients see a single-encoded JSON object instead of the doubly-escaped text that resulted from JSON-encoding a JSON string at the transport layer.

session_helpers.envelope_failure(error: str, *, stdout: str = '', stderr: str = '', **extras: Any) dict[str, Any]#

Build a failure envelope as a plain JSON-safe dictionary.

See envelope_success() for the rationale behind returning a dictionary instead of a JSON string.

session_helpers.render_envelope_from_execute(execute_result: dict, *, on_success_payload: Any | None = None) dict[str, Any]#

Convert a PersistentPythonSession.execute result to our envelope.

If on_success_payload is provided, it overrides the parsed-from-stdout payload. Otherwise, an attempt is made to parse the last JSON line from stdout.