MandAPI
English ▾
Build application workflows

Build a small terminal interface for your agent

Expose progress, reference reads, and resumable steps with a portable Python terminal interface.

Use this recipe with your coding assistant

Read the prompt
Add a standard-library Python terminal interface around the existing MandAPI headless worker. Reuse load_state and step instead of duplicating the agent logic. Support /next for one admitted request, /status and /quit; show the attempt count and read-only tool events. Preserve checkpoint identity and limits. Strip terminal control characters from displayed model output. Do not add a shell, arbitrary file reader, external actions or a hosted agent claim. Provide --demo and dependency-free offline tests with scripted input: unknown command makes no model call; quit makes no model call; two next commands complete the demo; reopening a completed checkpoint makes no call. Live requests, if a user chooses them later, use MANDAPI_API_KEY and MANDAPI_MODEL_ID at https://api.mandapi.com/v1/chat/completions. Do not run paid requests or deploy.
TXT

Put a terminal interface around the same worker

A terminal interface should reveal what the application is doing: which step ran, which reference was read, and whether the task finished. Reuse mandapi_worker.py from the headless guide. This small, portable interface uses standard Python input and output rather than a separate agent SDK.

Save the code as agent_tui.py beside that module. /next admits one step, /status shows saved progress, and /quit leaves the last checkpoint available. Only the fixed reference reader is enabled. The interface does not grant the model shell access or create a hosted MandAPI agent.

Add the interface

python
import argparse
import os
from pathlib import Path
from mandapi_worker import load_state, step, chat, demo, MAX_STEPS


def safe(text):
    return "".join(c for c in str(text) if c.isprintable() or c == "\n")


def show_event(event):
    if event["event"] == "read":
        print("  reference:", safe(event["name"]))
    elif event["event"] == "done":
        print("  answer:", safe(event["answer"]))
    else:
        print("  status:", safe(event["event"]))


def run_ui(state, checkpoint, ask, read=input):
    while state["status"] == "ready":
        print("\n+--- MandAPI demo assistant ---+")
        print("attempts:", state["attempts"], "/", MAX_STEPS)
        print("/next = one step | /status | /quit")
        command = read("> ").strip()
        if command == "/quit":
            return state
        if command == "/status":
            print("status:", safe(state["status"]))
        elif command == "/next":
            print("working...", flush=True)
            step(state, checkpoint, ask, show_event)
        else:
            print("Unknown command")
    print("status:", safe(state["status"]))
    if state["result"]:
        print(safe(state["result"]))
    return state


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("job")
    parser.add_argument("--checkpoint", type=Path, default=Path("tui-run.json"))
    parser.add_argument("--demo", action="store_true")
    args = parser.parse_args()
    model = "offline-demo" if args.demo else os.environ["MANDAPI_MODEL_ID"]
    state = load_state(args.checkpoint, args.job, model)
    try:
        run_ui(state, args.checkpoint, demo if args.demo else chat)
    except (EOFError, KeyboardInterrupt):
        print("\nStopped; the last saved checkpoint remains available.")
    except (OSError, ValueError, KeyError, TypeError, IndexError) as error:
        print("Stopped:", type(error).__name__)
        raise SystemExit(1)

Try the interaction

Run python agent_tui.py "How long does demo shipping take?" --demo --checkpoint tui-demo.json. Enter /status, then /next twice. Expect a reference name and a final answer. Repeat the command with the same task and checkpoint to see the completed result without another model call.

For live chat, set MANDAPI_API_KEY and a suitable MANDAPI_MODEL_ID, omit --demo, and use a new checkpoint. The reused worker sends ordinary requests to https://api.mandapi.com/v1/chat/completions; every admitted live step can consume credits. It displays a waiting message and then the completed step, rather than token streaming.

Verify the controls

Try an unknown command and confirm it makes no request. Quit before /next and confirm the model was never called. Test an invalid model action and verify the worker rejects it. Display text removes terminal control characters before printing; avoid rendering raw model output as escape sequences.

Stopping the UI does not cancel an already accepted remote request. A failed or interrupted attempt remains counted. For unattended execution, keep the same worker and follow resumable tasks.

References

Topics inspired by public documentation; instructions and examples adapted for MandAPI.