agenttru.st

Gaston bronze

gaston.xmmersia.com

The Conductor — user-facing tutor for Xmmersia. In Training Hub, orchestrates Le Marteau (worksheet generation), Le Veilleur (progress tracking), and Lumière (grading) for personalized practice across derivatives, partial derivatives, algebra, and graphing. In L'Étude, serves as the course-grounded text tutor (stateless tutor_answer skill over a Portal-built corpus). Also provides report discussion (Le Bilan), briefing generation, and class-broadcast composition.

a2a https://gaston.xmmersia.com talk to it https://gaston.xmmersia.com/.well-known/agent.json its card
🇩🇪 DE · Hetzner Online GmbH Checked 6d ago extensions, pushNotifications, stateTransitionHistory, streaming

we checked this    the operator says this

Community rating 0 0 up · 0 down — sign in to vote

Verified by agenttru.st

Everything here is a check agenttru.st performed itself. Assurance, protocol, hosting and freshness are in the card above and are not repeated.

Certificate
Issued by Let's Encrypt domain-validated
Valid until 19 Nov 2026.
Control of the hostname was checked; nothing about who operates it.
DANE / TLSA
Not verified
Discovery
Well-known document
First seen
29 Aug 2026
View verification details
Assurance
bronze Bronze — agent card fetched over HTTPS with a valid certificate
Protocols
A2A verified by handshake or card fetch, not merely advertised
Hosted in
🇩🇪 DE · Hetzner Online GmbH (AS24940)
Last checked
6d ago

What this agent says it can do

Declared in the agent's own card. agenttru.st has not tested whether it completes any of these tasks — the operator of gaston.xmmersia.com controls every word below.

Chat with Gaston

LLM-powered conversation about progress, insights, and class performance. Uses GPT-4o-mini to provide intelligent responses based on Le Veilleur data. Does NOT accept an offering_id and reads the pinned default offering only — deliberately: it grounds every answer in Le Veilleur's get_class_overview, which takes no offering parameter in v5.59.0, so threading only the conditional get_progress read would build one answer out of two offerings' trees with nothing marking the seam. Blocked on Le Veilleur; do not send an offering_id, it would be discarded.

chatllminsightsoffering-blind
Examples it gives
  • {"skill": "chatbot", "parameters": {"message": "How is the class doing on chain rule?"}}
  • {"skill": "chatbot", "parameters": {"message": "Which students need the most help?"}}

Discuss Assessment Reports

Student-facing conversation about Lucie assessment reports. Gaston as analyst with access to real Gradescope feedback. Fetches reports from Le Veilleur and provides grounded, helpful responses. Accepts an optional offering_id, forwarded to its single Le Veilleur call (get_reports) and folded into the 5-minute report cache key — keying the cache on computing_id alone would serve one offering's reports for another's request inside the TTL, which no amount of correct threading on the call itself would prevent. Omitted or null resolves against the pinned default offering.

chatllmstudentreportsluciele-bilanfeedbackoffering-aware
Examples it gives
  • {"skill": "discuss_reports", "parameters": {"computing_id": "abc123", "message": "What did I get wrong on Lecture 01 Quiz?", "offering_id": "1"}}
  • {"skill": "discuss_reports", "parameters": {"computing_id": "abc123", "message": "Can you explain opportunity cost?", "conversation_id": "abc123-bilan"}}

Generate Briefing

Generate a two-section Lucie report briefing (Strengths / Focus Areas). Takes pre-fetched reports, progress, and optional previous_briefing as input; returns structured briefing dict. Used by Le Veilleur's async task worker to keep briefing generation off the Vercel serverless path.

analystbriefingbureaule-bilangemini
Examples it gives
  • Generate a briefing for student efg3vv with their reports and progress

Request Practice Worksheet

Orchestrate personalized worksheet generation. Gets student progress from Le Veilleur, requests worksheet from Le Marteau, logs the session with PDF storage for re-download. Relays the optional topic param to Le Marteau (derivatives, partial_derivatives, algebra — solve-for-x + simplify-by-canceling — and, since v3.49.0, graphing); when omitted, Le Marteau's default applies. GRAPHING TAKES A DIFFERENT GENERATION SKILL AND NO SECOND PDF HOP: topic=graphing routes to Le Marteau's generate_graphing_worksheet, which mints the same T-{term}-Math-Graphing-{seed}-{ts} worksheet id the rest of the family uses, renders its problems PDF in-process (reportlab, not LaTeX) and returns pdf_base64 / pdf_filename on the response, so render_pdf is not called. No difficulty distribution and no focus_topics are sent — the graphing ladder is authored in Le Marteau — and no count, a graphing worksheet being exactly ten. THE STORED ANSWER KEY IS REBUILT FROM A PER-TRAINING-TYPE ALLOWLIST (v3.49.0). Derivatives, partials an

practiceworksheetgenerationorchestrationstudentpdfoffering-awarefocus-overridegraphing
Examples it gives
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123"}}
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123", "problem_count": 15}}
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123", "offering_id": "1"}}
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123", "topic": "derivatives", "focus_override": {"mode": "work", "topics": ["quotient"]}, "offering_id": "1"}}
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123", "topic": "derivatives", "focus_override": {"mode": "mix"}, "offering_id": "1"}}
  • {"skill": "request_worksheet", "parameters": {"student_id": "abc123", "topic": "partial_derivatives", "switch_from_session_id": "T-26Sp-Math-Derivatives-847291-1710432000", "offering_id": "1"}}

Re-download Worksheet

Retrieve a worksheet PDF for re-download. If no session_id provided, returns the pending worksheet. Used when student needs to re-download their worksheet. Accepts an optional offering_id, forwarded to its single Le Veilleur call (get_worksheet) so the PDF is fetched from the offering the session lives in. Omitted or null resolves against the pinned default offering.

worksheetpdfdownloadretrievalstudentoffering-aware
Examples it gives
  • {"skill": "get_worksheet", "parameters": {"student_id": "abc123"}}
  • {"skill": "get_worksheet", "parameters": {"student_id": "abc123", "session_id": "WS-26Sp-123456-1234567890", "offering_id": "1"}}

Get Worksheet Problems

Retrieve the problems list for a worksheet session (online worksheet modal). Forwards to Le Veilleur; strips grading-side fields (answer, answer_forms, answer_latex). Passes error codes through. Accepts an optional offering_id, forwarded to its single Le Veilleur call so the modal reads the problems from the same offering's tree the session was written into — pass the same offering here that request_worksheet was given, or the modal opens empty. Omitted or null resolves against the pinned default offering.

worksheetproblemsonlinemodalretrievalstudentoffering-aware
Examples it gives
  • {"skill": "get_worksheet_problems", "parameters": {"student_id": "abc123", "session_id": "WS-26Sp-123456-1234567890", "offering_id": "1"}}

Grade Typed Submission

Conductor wrapper for typed worksheet grading. Since v3.40.0 a pre-grade status guard runs FIRST, ahead of the answer-key fetch: unless the caller passes allow_regrade, Gaston reads Le Veilleur's get_session_status for this student/session and refuses any session that is not pending — error_code session_expired for an expired session, session_already_graded for anything else — returning {success: false, error_code, message, session_id, logged: false} without fetching the key, without calling Le Marteau and without logging. This closes a replay: Portal's submit route validates only the session-id format and get_answer_key returns the key for a session in any status, so a student who had already submitted once (and had therefore seen every correct answer in review mode) could re-POST the same session_id with the perfect set and have it graded and logged again. allow_regrade is the one authorized bypass, set only by Le Veilleur's server-side staff-regrade worker, whose payload is otherwise key-identical to a

gradingconductortraining-hubtypedmathliveoffering-awarepending-onlyreplay-guardgraphingproblem-unit-counters
Examples it gives
  • {"skill": "grade_typed_submission", "parameters": {"student_id": "abc123", "session_id": "WS-26Sp-123456-1234567890", "training_type": "derivatives_worksheet", "answers": [{"problem_number": 1, "student_answer_latex": "6x+2"}, {"problem_number": 2, "student_answer_latex": "\\frac{2x}{x^2+1}"}, {"problem_number": 3, "student_answer_latex": "e^x+xe^x"}, {"problem_number": 4, "student_answer_latex": "3x^2"}, {"problem_number": 5, "student_answer_latex": "\\cos x"}]}}
  • {"skill": "grade_typed_submission", "parameters": {"student_id": "abc123", "session_id": "WS-26Sp-123456-1234567890", "training_type": "derivatives_worksheet", "modality": "typed_mathlive", "answers": [{"problem_number": 1, "student_answer_latex": "6x+2"}, {"problem_number": 2, "student_answer_latex": "\\frac{2x}{x^2+1}"}, {"problem_number": 3, "student_answer_latex": "e^x+xe^x"}, {"problem_number": 4, "student_answer_latex": "3x^2"}, {"problem_number": 5, "student_answer_latex": "\\cos x"}]}}

Get Progress Report

Retrieve a student's progress report from Le Veilleur. Shows same data to students and TAs for transparency. Accepts an optional offering_id, forwarded to its single Le Veilleur call so the report is read from the named offering. Omitted or null resolves against the pinned default offering.

progressreporttransparencystudenttaoffering-aware
Examples it gives
  • {"skill": "get_progress", "parameters": {"student_id": "abc123"}}
  • {"skill": "get_progress", "parameters": {"student_id": "abc123", "offering_id": "1"}}

Download Student Work

Package and download all student work (worksheets, submissions, grades) from Le Veilleur. Accepts an optional offering_id, forwarded to its single Le Veilleur call (get_student_data) so the export covers the named offering. Omitted or null resolves against the pinned default offering — note that an export is per-offering, not a union across offerings.

downloadexportdatastudentoffering-aware
Examples it gives
  • {"skill": "download_work", "parameters": {"student_id": "abc123"}}
  • {"skill": "download_work", "parameters": {"student_id": "abc123", "offering_id": "1"}}

Request Budget Quiz

Generate a budget-constraint quiz as a PENDING worksheet-lifecycle session, and that is this skill's ONLY flow (v3.65.0): the spring pass-through — one Le Marteau hop, an ephemeral BQ- id, no pending record, no offering anywhere — is REMOVED, not deprecated, and no lifecycle parameter on this skill reaches back to it. Step 0 is request_worksheet's Step 0, structurally verbatim: Le Veilleur check_pending BEFORE any generation, so a refusal costs no SymPy, and a stale session auto-expires on the way. THE ONE PENDING SLOT IS FLEET-WIDE AND BUDGET IS IN IT — an open derivatives, partial-derivatives, algebra or graphing worksheet refuses a budget quiz exactly as a budget quiz refuses them — and the refusal payload is the worksheet path's pending_session_exists shape KEY FOR KEY (success:false, error_code, session_id, expires_at, time_remaining_hours, message), because the Portal interstitial that renders it is one component and must not learn a second dialect; its fallback message is deliberately NOT budge

quizbudgetpracticeinteractivestudentworksheet-lifecyclepending-sessionorchestrator
Examples it gives
  • {"skill": "request_budget_quiz", "parameters": {"student_id": "abc123"}}
  • {"skill": "request_budget_quiz", "parameters": {"student_id": "abc123", "offering_id": "Econ3010-26F", "domain": "general", "count": 5}}

Request Isoquant Quiz

Generate isoquant estimation quiz problems for interactive Quiz Mode. Calls Le Marteau's generate_isoquant_quiz skill and returns problem data for the React component.

quizisoquantpracticeinteractivestudent
Examples it gives
  • {"skill": "request_isoquant_quiz", "parameters": {}}
  • {"skill": "request_isoquant_quiz", "parameters": {"difficulty": 2, "count": 3}}

Request Graphing Session

Generate a ten-problem Graphing session (five single lines, then five continuous piecewise functions) for the Graphing room. Calls Le Marteau's generate_graphing_session and returns the session WITHOUT any answer key: each problem is rebuilt from an allowlist of number / kind / problem_text / axes / grid, so the intercept, the slopes, the kink x-values and the solution segments never reach a browser — an allowlist rather than a deletion, because a denylist would leak the first key-bearing field added to the generator. template_id and level are dropped too (a template id names the shape of the piecewise function). Accepts an optional offering_id and FORWARDS it to Le Marteau — omitted entirely when the caller sends none — because Le Marteau resolves the {term} segment of the GW-{term}-{seed}-{timestamp} session id from it. The session id is returned exactly as minted; Gaston mints none and rewrites none. Synchronous, like request_budget_quiz: one JSON-RPC call, answered in the same response, no queue. Re

quizgraphingpracticeinteractivestudentanswer-key-withheldoffering-aware
Examples it gives
  • {"skill": "request_graphing_quiz", "parameters": {}}
  • {"skill": "request_graphing_quiz", "parameters": {"student_id": "abc123", "offering_id": "Econ3010-26F", "seed": 847291}}

Get Class Overview

Retrieve class-wide analytics for the TA Dashboard. Shows all students sorted by status (red first). Does NOT accept an offering_id and reads the pinned default offering only — Le Veilleur's get_class_overview takes course / semester / sort_by / filter_status and no offering parameter in v5.59.0, so there is nothing for Gaston to forward. Blocked on Le Veilleur; this skill becomes offering-aware the moment Le Veilleur's does.

dashboardclassanalyticsoffering-blind
Examples it gives
  • {"skill": "get_class_overview", "parameters": {}}

Request Cost Minimization Quiz

Generate cost minimization quiz problems for interactive Quiz Mode. Calls Le Marteau's generate_cost_minimization_quiz skill and returns problem data for the React component.

quizcost-minimizationpracticeinteractivestudent
Examples it gives
  • {"skill": "request_cost_minimization_quiz", "parameters": {}}
  • {"skill": "request_cost_minimization_quiz", "parameters": {"mode": "mixed", "count": 10}}

Submit Cost Minimization Result

Submit completed Cost Minimization quiz results. Generates personalized LLM analysis and a branded PDF report. Returns report + PDF to Portal. Self-graded client-side; does not log to Le Veilleur. Makes one read from Le Veilleur — get_student_data, only when the caller omits student_name — and accepts an optional offering_id which is forwarded to it, so the name on the PDF is read from the right offering's profile. Omitted or null resolves against the pinned default offering.

quizcost-minimizationresultreportpdfstudentoffering-aware
Examples it gives
  • {"skill": "submit_cost_minimization_result", "parameters": {"computing_id": "abc123", "session_id": "TQ-26Sp-12345-1710432000", "score": 8, "total": 10, "accuracy": 80, "offering_id": "1"}}

Submit Budget Session

Orchestrate end-of-session for a completed Budget Quiz: generate the Gaston analysis report, call Le Veilleur render_and_log_budget_session (which renders both PDFs, persists them to Box and logs the session via log_completed_session), return report + PDFs to the Portal. IT TAKES AN OFFERING NOW (v3.65.0). This was Gaston's LAST offering-blind write, and the block was Le Veilleur's rather than Gaston's: render_and_log_budget_session took no offering parameter at all until Le Veilleur v5.129.0, so every budget PDF and every profile counter its delegate moved landed in the pinned default tree whatever offering the student was working under. It now forwards one to every storage call and across the log_completed_session hop, so the optional offering_id goes on the request; absent/None still resolves the pinned default, byte-identical to before. THE CLIENT'S RESULT ROWS ARE FORWARDED UNTOUCHED — problem_number, correct, rules[], the per-part rows, student_segments, the typed slopes and the legacy number/is_corre

budget-constraintsessionsubmittraining-huborchestratoroffering-awareworksheet-lifecycle
Examples it gives
  • {"skill": "submit_budget_session", "parameters": {"computing_id": "abc123", "offering_id": "Econ3010-26F", "session_id": "T-26F-Economics-Budget-847291-1786071569", "problems": [], "score": 4, "total": 5}}

Request IC Quiz

Generate a Sketch Indifference Curves session — the Preferences room's one training, training_type "ic_quiz" — as a PENDING worksheet-lifecycle session (v3.67.0). request_budget_quiz's SIBLING, step for step, with three names changed: Le Marteau's generate_ic_quiz in place of generate_budget_quiz, the training_type literal, and the log lines. Step 0 is Le Veilleur check_pending BEFORE any generation; the one pending slot is fleet-wide, and the refusal is the worksheet path's pending_session_exists payload KEY FOR KEY (success:false, error_code, session_id, expires_at, time_remaining_hours, message), its fallback message the budget mint's own constant, imported rather than copied. Calls generate_ic_quiz with budget's request shape — domain, level, count, lifecycle="pending", student_id, and offering_id OMITTED when absent — which mints T-{term}-Economics-Preferences-{seed}-{timestamp}, then writes the pending record through log_session carrying the seed, created_at, problem_count, training_type "ic_qui

quizindifference-curvespreferencespracticeinteractivestudentworksheet-lifecyclepending-sessionorchestrator
Examples it gives
  • {"skill": "request_ic_quiz", "parameters": {"student_id": "abc123"}}
  • {"skill": "request_ic_quiz", "parameters": {"student_id": "abc123", "offering_id": "Econ3010-26F", "domain": "general", "count": 5}}

Submit IC Session

Orchestrate end-of-session for a completed Sketch Indifference Curves session (v3.67.0): generate the Gaston analysis report, call Le Veilleur render_and_log_ic_session (to render both PDFs, persist them to Box and log the session via log_completed_session), return report + PDFs to the Portal. submit_budget_session's SIBLING, with one call renamed: render_and_log_ic_session is created by Le Veilleur's Preferences brief and is sent render_and_log_budget_session's parameters KEY FOR KEY (student_id, student_name, session_id, problems, score, total, accuracy, report_text, duration_seconds, offering_id). Until Le Veilleur ships it, the call answers with an A2A error and this skill returns render_failed with the report attached. Optional offering_id is forwarded; absent/None resolves the pinned default. THE CLIENT'S RESULT ROWS ARE FORWARDED UNTOUCHED, by reference — four kinds: one SKETCH row per problem (the generated problem spread whole, so utility_text, k_level and direction ride on it), and the COUNT ("N-c

indifference-curvespreferencessessionsubmittraining-huborchestratoroffering-awareworksheet-lifecycle
Examples it gives
  • {"skill": "submit_ic_session", "parameters": {"computing_id": "abc123", "offering_id": "Econ3010-26F", "session_id": "T-26F-Economics-Preferences-847291-1786071569", "problems": [], "score": 4, "total": 5}}

Submit Graphing Session

Orchestrate end-of-session for a completed ten-problem Graphing session: call Le Veilleur's render_and_log_graphing_session (which grades per SUB-ANSWER — three independently verdicted, independently rule-tagged sub-answers per problem — renders both PDFs, persists them to Box and logs the session via log_completed_session), then write the Gaston report FROM the graded rows and return report + graded rows + PDFs to the Portal. GASTON GRADES NOTHING AND TAGS NOTHING: the rule tags are Le Marteau's, authored at generation; the verdicts are Le Veilleur's; this skill carries the problems list verbatim. Accepts an optional offering_id and FORWARDS it — Le Veilleur's graphing skill threads it to every storage call and across the log hop, which is what makes this path offering-aware from its first release, unlike submit_budget_session. The session id passes through unchanged. THE REPORT IS WRITTEN AFTER GRADING, not before, because Gaston does not know the score until Le Veilleur answers — so the report reac

graphingsessionsubmittraining-huborchestratoroffering-awareserver-graded
Examples it gives
  • {"skill": "submit_graphing_session", "parameters": {"computing_id": "abc123", "session_id": "GW-26F-847291-1786071569", "offering_id": "Econ3010-26F", "problems": []}}

Book Session

Book a 1:1 tutoring session — validates the requested time, refuses a booking whose student_computing_id is the offering's director or one of its TAs (individual sessions are booked by students), enforces the round's booking_opens date and the 6-hour booking lead time, keeps the one-active-booking-per-round invariant by REPLACING any booking the student already holds in that round rather than refusing (see A REBOOK REPLACES below), validates availability, creates the booking, generates an ICS calendar invite, sends the STUDENT's confirmation email (the TA is not mailed — see below). THE ROUND POLICY (v3.48.0): a round is a booking window authored per offering under course_config["booking"]["rounds"] — {id, label, opens, closes, booking_opens, duration_minutes, required}, inclusive on both ends, ids stable and never reused. The rule is ONE BOOKING PER STUDENT PER ROUND, checked after the time validation and BEFORE the availability call, so a refusal writes nothing and mails nobody. Exam weeks are express

bookingschedulingtraining-hubemailicsorchestrationwrite-confirmedround-policystudents-onlyroster-gatedcollision-verifiedrebook-replacescutoff-24h
Examples it gives
  • {"skill": "book_session", "parameters": {"student_computing_id": "abc2def", "ta_computing_id": "bds4xy", "date": "2026-04-14", "time": "14:00"}}
  • {"skill": "book_session", "parameters": {"student_computing_id": "abc2def", "ta_computing_id": "bds4xy", "date": "2026-08-26", "time": "14:00", "offering_id": "1"}}

Cancel Session

Cancel a booked 1:1 session — authorizes the canceller, updates status, sends the STUDENT an ICS cancellation that removes the calendar event (the TA is not mailed — see below). AUTHORIZATION (v3.45.0): cancelled_by was free text checked against nothing, so knowing a booking id — which is not a secret — was enough to cancel someone else's session and mail both parties about it. It must now match the booking's student_computing_id or ta_computing_id, or the call is refused with error "not_authorized" before any write and with no mail. The one sanctioned bypass is staff_override (bool, default false), a named path for a director or TA acting on someone's behalf; it is deliberately NOT wired to any role lookup in this agent — the caller owns that check. The refusal message names no identifier, so it cannot be used to confirm who is on a booking. The already_cancelled check runs first, so a stranger learns nothing about a booking's state from the error code. THE CANCELLING WRITE IS CHECKED (v3.45.0): th

bookingcancellationemailicsorchestrationauthorizedwrite-confirmeddirector-cancelon-behalfcutoff-24h
Examples it gives
  • {"skill": "cancel_session", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "cancelled_by": "abc2def"}}
  • {"skill": "cancel_session", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "cancelled_by": "dir7kk", "staff_override": true, "reason": "TA out sick", "offering_id": "Econ3010-26Fa"}}

Mark No Show

Record that a booked student did not attend their 1:1 session — reads the record, authorizes the actor, checks that the session has started, writes status "no_show" on the whole stored record, verifies the write, and tells the student (v3.63.0 NEW). A SIBLING OF cancel_session, NOT A VARIANT OF IT: the only status a booking could leave "confirmed" for was "cancelled", and cancelling a session that HAPPENED is a false record — it says the hour was given back when in fact it was spent. THE STORE NEEDED NO CHANGE: Le Veilleur's save_booking writes the booking dict verbatim with no field whitelist and updates in place by id, and every reader in the fleet filters on status == "cancelled" and passes any other value through, so the whole of this feature is one Gaston skill and no Le Veilleur release. THE STORED RECORD gains no_show_marked_by (the actor's computing id), no_show_marked_at (UTC ISO) and no_show_reason (free text, "" when absent) alongside the new status; the rest of the record is written back intac

bookingattendanceno-showemailorchestrationauthorizedwrite-confirmedta-markedidempotent
Examples it gives
  • {"skill": "mark_no_show", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "actor_computing_id": "bds4xy"}}
  • {"skill": "mark_no_show", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "actor_computing_id": "dir7kk", "reason": "Waited 15 minutes", "offering_id": "Econ3010-26Fa"}}

Unmark No Show

Undo a no-show mark on a booked 1:1 session — reads the record, authorizes the actor, writes status "confirmed" back over "no_show" on the whole stored record, and verifies the write (v3.64.0 NEW). THE REVERSE WRITE mark_no_show SHIPPED WITHOUT: a mark made on a mistyped date, on the wrong row of a day, or on a student who walked in late was irreversible from every surface in the fleet, and the only remedy was a hand edit of the Box record — which is not a remedy a course can rely on. THE SKELETON IS mark_no_show's, MINUS TWO MORE STEPS. THERE IS NO CLOCK GATE: "has this session started" belongs to the MARK, which is an assertion about an hour that has been lived through; a correction of that assertion is not itself an assertion about the hour, and a record whose start cannot be read must still be correctable or a bad mark is permanent exactly where it is least defensible. THERE IS NO EMAIL, DELIBERATELY: the student was told once that they missed a session, and a second notice saying the first one was wr

bookingattendanceno-showreversalcorrectionorchestrationauthorizeddirector-onlywrite-confirmedidempotentno-email
Examples it gives
  • {"skill": "unmark_no_show", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "actor_computing_id": "ms3ae"}}
  • {"skill": "unmark_no_show", "parameters": {"booking_id": "BK-20260410-143022-abc", "date": "2026-04-14", "actor_computing_id": "ms3ae", "reason": "Student was in the room; wrong row marked", "offering_id": "Econ3010-26Fa"}}

Get Available Slots

Get available time slots for a TA on a specific date. Cross-references availability with existing bookings, and omits any slot starting inside the 6-hour booking lead time - since v3.61.0 what this returns is what book_session would accept, so the picker no longer offers a time the write refuses on the click. all_slots and booked_slots are unfiltered: they describe the TA schedule, not what is on offer. An unreadable date or time drops the slot, matching the write invalid_time refusal.

bookingavailabilitytraining-hub
Examples it gives
  • {"skill": "get_available_slots", "parameters": {"ta_computing_id": "bds4xy", "date": "2026-04-14"}}

Get Available Slots (Bulk)

Get available time slots for a whole (TA x date) matrix in ONE call - the calendar picker's prefetch, replacing one get_available_slots round-trip per cell. Passthrough to Le Veilleur's get_available_slots_bulk. Takes ta_computing_ids plus either dates or an inclusive start_date/end_date range; optional offering_id and duration_minutes are echoed and do not filter. Returns one cell per requested pair, each carrying exactly what get_available_slots returns for that pair, plus per-cell 'complete' - a failed read is never an empty day. Since v3.61.0 each cell's available_slots omits any slot starting inside the 6-hour booking lead time, by the same rule and the same constant get_available_slots and book_session use; a cell that empties is returned present and EMPTY rather than removed, and a failed cell (result null) is untouched. Cell count, cell order, 'complete' and failed_cells are as Le Veilleur sent them. get_available_slots stays as the single-pair call and the fallback.

bookingavailabilitybulktraining-hub
Examples it gives
  • {"skill": "get_available_slots_bulk", "parameters": {"ta_computing_ids": ["bds4xy", "ttt4tt"], "dates": ["2026-08-25", "2026-08-26"], "offering_id": "MATH1220-26Fa"}}

Get Booking Rounds

The offering's booking rounds with this student's status in each — what the Le Foyer calendar page and card render ("Individual Session 2 — book by Sept 18", and whether it is already taken). Parameters: student_computing_id (required), offering_id (optional, forwarded to get_course_config only; the bookings read is course-level and carries no offering). Reads the rounds from course_config["booking"]["rounds"], then makes ONE get_student_bookings call spanning the earliest opens to the latest closes across all rounds — not one call per round — and groups the results by round_id in memory. Returns {success, student_computing_id, offering_id, configured, today, complete, open_round_id, rounds[]}, rounds in window order, each carrying id, label, opens, closes, booking_opens, booking_open, duration_minutes, required, status and (when one exists) the booking record itself. Since v3.54.0 each round also carries location and location_directions, ALWAYS PRESENT and null when the round names no place — a key

bookingroundscalendartraining-hubread-onlyoffering-aware
Examples it gives
  • {"skill": "get_booking_rounds", "parameters": {"student_computing_id": "abc2def"}}
  • {"skill": "get_booking_rounds", "parameters": {"student_computing_id": "abc2def", "offering_id": "1"}}

Book Office Hours

Book an office-hours meeting with the offering's host (v3.75.0 NEW, office-hours arc brief 4, design ruling seq 3038). Structurally parallel to book_session and on a POLICY PATH OF ITS OWN: no round, no round_id, no BOOKING_LEAD_TIME, no CANCELLATION_CUTOFF. Parameters: student_computing_id, date (YYYY-MM-DD), time (HH:MM), offering_id — all REQUIRED, the offering being the one the student books from — and optional student_name and student_email ({id}@virginia.edu by convention). There is NO duration parameter: the meeting length is always the block's. THE POLICY IS course_config.office_hours, read per offering off the same get_course_config read the round policy uses: {host_computing_id, host_name, duration_minutes, booking_lead_minutes, cancel_cutoff_hours, max_per_week, location_in_person, location_online, default_mode}. NO VALUE HAS A CODE DEFAULT — every number and string comes from the block, or the block is refused. No block at all is "office_hours_not_configured", a clean refusal; a block that i

bookingoffice-hoursschedulingemailicsorchestrationwrite-confirmedcollision-verifiedstudents-onlyroster-gatedweekly-capmodality
Examples it gives
  • {"skill": "book_office_hours", "parameters": {"student_computing_id": "abc2def", "date": "2026-09-16", "time": "15:00", "offering_id": "Econ3010-26Fa"}}

Request Office Hours

A student proposes an off-schedule office-hours time for the director to decide (v3.75.0 NEW, office-hours arc brief 4, ruling seq 3038). PENDING IS NOT A BOOKING: the request is written to Le Veilleur's request store (platform/office_hours/requests.json) through save_office_hours_request and NEVER to the bookings store, so no feed, board or reminder takes it for an appointment; only respond_office_hours_request turns one into a booking. Parameters: student_computing_id, offering_id, proposed_date (YYYY-MM-DD), proposed_time (HH:MM) — required — and optional note, student_name (defaults to the id) and student_email ({id}@virginia.edu). POLICY, IN ORDER: the offering's course_config.office_hours block present and valid ("office_hours_not_configured" / "policy_misconfigured" / "policy_check_unavailable"); not staff, then on the roster ("staff_cannot_book", "not_on_roster", "roster_unavailable"; a configured test account passes the roster by being listed); the proposed time parses and a meeting of the block'

office-hoursrequestpending-not-bookingstudents-onlyroster-gatedno-email
Examples it gives
  • {"skill": "request_office_hours", "parameters": {"student_computing_id": "abc2def", "offering_id": "Econ3010-26Fa", "proposed_date": "2026-09-17", "proposed_time": "15:30", "note": "Can't make the posted hours."}}

Respond to Office Hours Request

The director accepts or declines a pending office-hours request (v3.75.0 NEW, office-hours arc brief 4, ruling seq 3038). Parameters: request_id, decision ("accept" | "decline"), actor_computing_id — required — plus, on accept, mode ("in_person" | "online", REQUIRED — the toggle; a request carries no mode, the director chooses it), and on decline an optional reason. The request is RE-READ ("request_not_found"; "request_not_pending" once decided; a record not found in an incomplete store read is "specialist_unavailable", never not-found), its offering's office_hours block loaded ("office_hours_not_configured" / "policy_misconfigured" / "policy_check_unavailable"), and the actor must be that offering's director via is_offering_director ("director_only"). A bad decision or mode is "invalid_decision" / "invalid_mode", refused before any read. ACCEPT: the proposed time must still be valid for the block's duration ("invalid_time") and in the future; the WEEKLY CAP is re-run for that student AT DECISION TIME o

office-hoursrequestbookingdirector-onlyemailicswrite-confirmedcollision-verifiedmodality
Examples it gives
  • {"skill": "respond_office_hours_request", "parameters": {"request_id": "RQ-20260913-143022-a1f", "decision": "accept", "actor_computing_id": "ms3ae", "mode": "online"}}
  • {"skill": "respond_office_hours_request", "parameters": {"request_id": "RQ-20260913-143022-a1f", "decision": "decline", "actor_computing_id": "ms3ae", "reason": "Not that week."}}

Send Email Core

Shared email delivery spine — kill-switch check, test-account redirect, Resend send, archive via Le Veilleur save_email. Callers compose; this skill delivers. Foundation for flash, broadcast, digest, and director emails. Accepts an optional offering_id (since v3.17.0, documented here as of v3.38.0) and forwards it to both Le Veilleur calls it makes: get_course_config, so the master and per-channel kill-switches and the test-account redirect resolve the right offering's email config, and save_email, so the archive record lands under the right offering's student tree. Omitted or null resolves against the pinned default offering.

emaildeliveryspinecoreresendoffering-aware

Compose Broadcast

Compose a broadcast email batch in one of three modes (verbatim / summary / per-student) and stage drafts via Le Veilleur's save_broadcast_draft. Composition only — sending happens later through send_email_core. Uses Gemini Flash for summary and per-student modes; verbatim uses no LLM. CANCELLABLE AND TASK-LINKED since v3.44.0: an optional task_id (sent by Le Veilleur v5.75.0+) is stamped onto the batch manifest and returned in the result, and every 10 recipients — starting before the first — the loop asks get_task_status whether that task is still alive. A task that reads cancelled or failed stops the compose, marks the manifest aborted (one last save carrying aborted=true, with the real staged count) and returns success=false with error "aborted_by_task_status" plus task_status and drafts_saved; Le Veilleur then refuses to send that batch. The guard is best-effort: a probe that times out or errors never aborts a compose, and a call with no task_id never probes at all. The result of a completed compose

emailbroadcastcomposegeminidraftoffering-aware

Send Audit Copy

Send the director an audit summary of a completed broadcast batch. One email per batch via the 'director' channel. Used by Le Veilleur task_worker after broadcast sends complete. Accepts an optional offering_id and carries it across both legs: its own Le Veilleur get_course_config read (which resolves the director's address from that offering's staff block — previously always the default offering's instructor) and the in-process hop into send_email_core, which threads it on to its own get_course_config and to save_email. Both legs or neither, or the director is resolved from one offering and their copy archived under another. Omitted or null resolves against the pinned default offering. v3.59.0: a batch composed with a cc list names the groups beside the audience and marks every recipient row as an `audience` email or a `cc copy`, so a staff member's copy is never read as evidence that staff were in the audience. A batch with no cc renders byte-identically to before.

emailauditbroadcastdirectorsummaryoffering-aware

Tutor Answer

Course-grounded tutor answers for L'Étude students. Gaston is the stateless reasoner: the Portal owns all gating, builds the released corpus for the viewer, and hands it over; this skill answers over exactly that corpus and nothing else — no fetching, no storage, no gating. Coaches toward method rather than handing over answers, and never produces an unreleased solution. Accepts an optional shared_work parameter — a PII-scrubbed transcription of course material the student photographed (the Portal scrubs it upstream) — assembled into the user turn and judged against the released corpus by the same closed-book principle: if the shared work is not released material the skill emits the [OUT_OF_UNIVERSE] sentinel for the Portal to render a warm decline, otherwise it helps the student with it. Emits a second sentinel on its own final line, [PRACTICE_OFFER], when a student asks for more practice — the Portal detects and strips it and renders its practice offer, which forge_practice_variant then fulfils; th

tutorllmstudentl-etudegroundedfireworksdeepseek
Examples it gives
  • {"skill": "tutor_answer", "parameters": {"question": "What is opportunity cost?", "corpus": "## Course\n...", "offering_id": "1", "course_meta": {"name": "Econ 4095", "today": "2026-07-08"}}}
  • {"skill": "tutor_answer", "parameters": {"question": "Please check my shared work", "shared_work": "Find dS/dt for S(t) = 2t + 3. Steps: ...", "corpus": "## Course\n...", "offering_id": "1", "course_meta": {"name": "Econ 4095", "today": "2026-07-08"}}}

Extract Tutor Memory

Fold a student's unabsorbed tutor transcript days into their tutor memory (Gaston Pillar 2). The companion to tutor_answer and just as stateless: the Portal reads the current memory and the raw transcripts from Le Veilleur's get_tutor_memory, hands both over, and owns the watermark (extracted_through) and the update_tutor_memory write — this skill neither fetches nor stores. Merges rather than replaces (a struggle the student has worked through moves to progress), keeps each list to about five items because the memory is re-read into the grounding corpus on every future exchange, and is identity-free by construction: the prompt forbids any name, computing ID, or email, and Le Veilleur's write path rejects a leak outright. Parses the model's reply defensively — an incomplete memory object is a failure, never a salvage. Uses Fireworks-hosted DeepSeek V4.1 Flash on the stateless chat.completions path. Calls no specialists.

tutormemoryllmstudentl-etudeextractionfireworksdeepseek
Examples it gives
  • {"skill": "extract_tutor_memory", "parameters": {"current_memory": null, "transcripts": {"2026-07-09": [{"question": "Why is the steady state stable?", "answer": "Let's look at the slope..."}]}, "offering_id": "1", "course_name": "Econ 4095"}}

Describe Agent

Compose a short (2–3 sentence) in-character blurb for one of the Xmmersia roster agents, keyed by agent_slug, for the Portal's 'Agent du Jour' login-page panel. Static self-descriptions covering all seven roster slugs (gaston, lumiere, le-marteau, le-veilleur, lucie, emile, diana) — no student data, no config reads, no LLM call, calls no specialists. Returns a `blurb` string; an unknown slug returns success=False with blurb=None so the caller falls back gracefully.

portalagent-du-jourrosterchroniclermeta
Examples it gives
  • {"skill": "describe_agent", "parameters": {"agent_slug": "le-marteau"}}
  • {"skill": "describe_agent", "parameters": {"agent_slug": "diana"}}

Transcribe Image

Transcribe an image of course material (lecture quiz, slide, or worksheet problem) into text and LaTeX for the tutor. Reads only — does not solve, grade, or judge. Kimi K3 vision on Fireworks.

visiontranscriptionl-etudestudentfireworkskimilatex
Examples it gives
  • {"skill": "transcribe_image", "parameters": {"image_base64": "<base64>", "media_type": "image/png"}}

Forge Practice Variant

Forge a new practice problem that is a structural twin of one a student wants more practice on (L'Étude): identical setup type and solution method, new parameter values and surface story, anchored to a transcribed original the tutor never invents from scratch. Produces a complete worked solution and, for numeric problems, a final answer, then self-verifies before returning — a second, cheap model independently checks the claimed answer (substitution) or, for a qualitative problem, that the solution addresses the problem as posed (structural). A failed check never ships silently: it regenerates once and, if the second attempt also fails, returns a warm graceful decline (error_code forge_failed) rather than an unverified problem or a stack trace. Bounded worst case — at most two generation attempts, ever. The forge model is configurable across providers: GASTON_FORGE_PROVIDER selects Fireworks (the shipped default, GLM 5.3) or Anthropic (claude-opus-4-8), and GASTON_FORGE_MODEL names the model on the activ

practicegenerationforgeverificationl-etudestudentfireworksanthropicglmclaudemulti-provider
Examples it gives
  • {"skill": "forge_practice_variant", "parameters": {"source_transcription": "A firm minimizes quadratic adjustment cost. Find k*.", "course_name": "Econ 4095"}}
  • {"skill": "forge_practice_variant", "parameters": {"source_transcription": "Explain why the steady state is stable.", "course_name": "Econ 4095", "lecture": "Lecture 10", "student_note": "focus on the slide-10 problem"}}

Daily Read

Phrase one of Clair de Lune's nightly domain rollups as a student-facing daily read for the Training Hub room page. Reads the rollup through Le Veilleur's get_clair_rollup (computing_id, domain — default "math" — and optional offering_id and date, all four forwarded on the single call; no date reads the latest rollup on disk), then writes 3-6 sentences in Gaston's debrief voice: warm, direct, second person, factual to the point of austerity — no empty encouragement, no exclamation marks, no emoji, and every sentence traceable to a specific fact. Numbers earn their place (the difficulty histogram lets it say when a strong result came on a deck weighted toward the harder problems), and misses are named from the rules_missed histogram without being diagnosed beyond it. Clair de Lune's own third-person synthesis string is never shown to the student — the read is synthesized fresh from facts[]. NEVER INVENTS: a deterministic pre-digest reduces the envelope to the fields actually present and the model sees

studenttraining-hubdaily-readclair-de-lunerollupllmoffering-awareread-only
Examples it gives
  • {"skill": "get_daily_read", "parameters": {"computing_id": "abc123"}}
  • {"skill": "get_daily_read", "parameters": {"computing_id": "abc123", "offering_id": "1", "domain": "math", "date": "2026-08-05"}}

Technical agent card

Copied from the agent's card. The operator controls these values; agenttru.st has not verified them.

Provider
Xmmersia — what this agent says about itself; other agents claiming the same provider are not thereby related
Protocol
a2a
Version
3.77.0
Extensions
https://xmmersia.com/extensions/education/v1 — required of clients
Educational tutoring and orchestration
https://xmmersia.com/extensions/llm/v1 — required of clients
LLM-powered conversational interface
A2A protocol extensions the card declares. A declared payment extension (AP2, x402) means the operator says the agent can transact, not that agenttru.st has seen it do so.
Card completeness
a2a.proto v1.0 requires eight top-level fields. This card omits:
supportedInterfaces
Missing fields do not affect listing — they describe how much the operator has published, not whether the agent was verified.
View all card details
Capabilities
extensions pushNotifications stateTransitionHistory streaming
Agent card
https://gaston.xmmersia.com/.well-known/agent.json

Operate this agent and would rather not be listed? Request removal.