lucky-math
Use the bundled math animation pipeline instead of inventing a one-off page. The pipeline deliberately separates recognition, confirmation, model creation, and rendering:
Runtime bundle requirement
This skill is distributed together with its runtime project. SKILL.md alone is
not a substitute for assets/, references/, scripts/, and examples/.
Those files provide the actual editor, animation library, JSON contract, OCR
adapters, and local server.
If the current installation contains only SKILL.md or cannot resolve
assets/math-animation.html, do not create a replacement viewer, copy a
partial implementation, or generate an equivalent one-off HTML file. Instead:
- Locate an existing complete lucky-math checkout in the workspace.
- If none exists, clone the canonical repository
https://github.com/megemini/lucky-math(ask the user for permission first), then use that checkout as the runtime project. - Run
scripts/serve.pyfrom the repository root and keep generated JSON, imported images, and library operations in that editor. When multiple Agent sessions are used, start them against the same served workspace root so the file-backeddata/library.jsonis shared across ports.
The repository checkout is the source of truth for editor behavior. A skill-only installation may still provide these instructions, but it cannot provide the editor or animation library by itself.
When the editor is served by scripts/serve.py, it uses the server-backed
library API and stores the shared library in data/library.json. Opening the
HTML directly remains a supported static fallback, but its library is
origin-local and will not automatically be shared across ports or sessions.
The server can temporarily serve legacy absolute image paths only when they are
inside the selected --workspace-root; new documents must still use portable
relative paths.
- Collect input. Accept one or more LaTeX strings, or one or more image paths. Keep every source image attached to the resulting document.
- Choose recognition. If the current model has vision, ask it to read the
formula and preserve the original image. If it does not, run
python scripts/ocr_formula.py image1.png image2.png. OpenVINO is the default backend and uses the promptFormula Recognition:; the script also supportsapi,mcp,local, ornonethroughLUCKY_MATH_OCR_BACKEND(or the corresponding CLI option). Never expose OCR tokens in output. - Confirm before rendering (gate, cannot be skipped). Before building the
document, the user must confirm exactly two things; everything else is left
to the model's discretion and should be prompted only when genuinely
ambiguous or high-risk.
- (a) Formula recognition. Present the normalized LaTeX for every image, including an uncertainty note when applicable. Do not silently correct a symbol. Ask the user to confirm or edit each formula.
- (b) Variable parameters (slots). Present the proposed adjustable
parameters for each formula together with their
value,min,max,step, andlabel. Ask the user to confirm, add, remove, or retune the ranges. Trigonometric formulas still expose the canonicalamplitude,frequency,phase, andverticalShiftslots, but the user must confirm they are appropriate. Discretionary items — prompt only when there is genuine ambiguity or risk (for example a blank or offset canvas, or a sensitive unit assumption): the displayview/domain(andyDomainfor implicit curves), radians versus degrees for trigonometry, the role of the independent variable, animation-specific parameters, and multi-formula grouping/intersections. This confirmation gate cannot be skipped.
- Choose motion. Ask whether the user wants a moving sample point, a
left-to-right trace, a parameter sweep, a time-dependent curve, or a static
graph. Put that choice in the document's
animationobject; do not invent a visually busy motion when a static explanation is clearer. - Build the document. Convert confirmed formulas into the JSON contract in
references/schema.md. For an explicit curve, provide a safe numericexpressionevaluated asy=f(x,t). For an implicit curve, usetype:"implicit"and provide a safe zero-contour expressionF(x,y,t)=0. Keep the originallatexbeside it. Put adjustable quantities inslots, not hidden constants in JavaScript. The slots written here must already have been confirmed with the user in step 3(b); do not silently invent new adjustable parameters at build time.sourceImagesmust use paths relative to the JSON document (or data/HTTP URLs), never machine-specific absolute filesystem paths. If an image is outside the served runtime root, copy it into the project image directory or use a data URL before writing the document. For every visiblesin,cos, ortancurve, expose its amplitude, frequency, phase, and vertical shift as slots even when the source formula omits some of them. For example,y=3sin(2x+π/3)must become an expression using slots with valuesamplitude=3,frequency=2,phase=π/3, andverticalShift=0;y=cos(x)should expose the same four values as1, 1, 0, 0. Use distinct slot ids for different formulas. When the user provides multiple screenshots or asks for multiple formulas, aggregate all confirmed results into one document: onesourceImagesarray, oneformulasarray containing every curve, and one shared canvas. Never create one JSON file or library card per screenshot/formula unless the user explicitly requests separate animations. Before saving, verify that the number of intended formulas equalsformulas.length. Optionally add atipsarray for teaching annotations anchored at key curve locations (seereferences/schema.md); each tip needs a stableidthat doubles as the conversation handle the user can reference later. Write the confirmed document intodata/documents/<slug>.json(for exampledata/documents/sine-wave.json) inside the runtime checkout or the served--workspace-root, and copy any source screenshots intodata/images/. This is the canonical location for generated documents; do not scatter them in the project root,examples/, or alongsidedata/library.json. Keep names portable (<slug>from the title): no absolute machine paths. - Render. Start from
assets/math-animation.html. It provides a uniform coordinate system, grid, axes, asymptotes, explicit and implicit curves, labels, multiple curves, a time parameter, point probing, and drawing tools. It works without a build step. After writing a document, open that exact JSON file, not the defaultexamples/sine.jsonand not a rebuilt copy, for examplepython3 scripts/serve.py --open --document data/documents/sine-wave.json. If the JSON is outside the Skill directory, start the server with the containing workspace as--workspace-rootand pass the document with--document. The server will generate a root-relativedocumentURL, so nested.trae/skills/...paths do not change which JSON is loaded. Verify the URL contains the generated document and that the editor shows every item informulasbefore saving it. - Save and iterate. After the user confirms the document, ask whether it
should be added to the animation library. Load the complete document first,
then use Save to Library once; do not save each OCR result separately. When
the editor is available, use its Save to Library action and assign
category/tags. When the Agent has only filesystem access, save the confirmed
JSON into the complete runtime checkout and clearly tell the user that it
still needs to be imported or opened by the editor; do not claim that
browser
localStoragewas changed. Changes to slots, view bounds, visibility, and drawing layers take effect immediately.
Agent rules
- Explain whether recognition came from vision, OCR API, MCP, local OCR, or direct LaTeX input.
- For multiple formulas, use one document and one shared canvas unless the user explicitly asks for separate views. Give each formula a stable id and color.
- Prefer the built-in primitives (
axis,grid,asymptote,text,line,circle,rect, andimplicitformulas) over custom drawing code. Usereferences/components.mdas the vocabulary and defaults. - Expose meaningful slots such as amplitude, frequency, phase, center, radius, and vertical shift with bounds, step, and a visible label. Keep the number of slots small enough to understand.
- Use the plotter expression only for rendering. It is not a proof engine: state domain restrictions, discontinuities, and numerical limitations in the explanation.
- Use
type:"implicit"for circles, ellipses, parabolas, hyperbolas, level curves, and other equations that cannot be safely reduced toy=f(x). Give implicit formulas bothdomainand, when useful,yDomain; do not pretend that an implicit equation is an explicit formula. - Always write generated documents to
data/documents/and source screenshots todata/images/inside the runtime checkout or served--workspace-root. Never place them in the project root,examples/, or next todata/library.json. This keeps generated output in one place and unambiguous. - Preserve accessibility: give the canvas a description, label controls, expose probe values in live text, and do not make color the only distinction.
- Attach teaching tips to key curve locations (zeros, extrema, asymptotes,
intersections, periods) via the document
tipsarray. Give every tip a stable id (t1,t2, ...). Because the agent authors these tips they already live in the conversation context; after generating a plot with tips, list the tip ids in your reply (for example "已标注:t1 零点、t2 极大值") and tell the user they can continue the discussion by referring to those ids. The number of tips is not fixed: add exactly the genuinely instructive key points (anywhere from zero to several per curve), and skip them entirely for straight static lines with nothing worth annotating. Thet1/t2count inexamples/sine.jsonis only an illustration, not a required quantity. Tipx/yare static snapshots, so for parameter-sensitive key points (for example the sine maximum that moves when the user dragsfrequency) either anchor at a parameter-independent location (such as a fixed zero), or state inbodythat the tip corresponds to the default parameter values; otherwise the tip drifts off the curve when a slot changes. - Do not run local OCR validation unless the user says the local model is ready; the local adapter is included but intentionally not exercised by the default checks.
Useful commands
python scripts/ocr_formula.py --help
python scripts/ocr_formula.py --backend none formula.png
python scripts/validate_bundle.py
To help the user preview a document, run python scripts/serve.py --open; the
skill may also load a JSON automatically with
python scripts/serve.py --open --document examples/sine.json. The server is
local-only by default and stops with Ctrl-C. Users can also open
assets/math-animation.html directly and use the Library tab to import JSON.
OCR configuration
Copy .env.example to .env. OpenVINO is the default backend;
LUCKY_MATH_OPENVINO_MODEL_DIR optionally points at a local model. If
the model directory is missing or invalid, the adapter downloads the OpenVINO
model from ModelScope. Its model prompt is fixed to Formula Recognition:. api
follows the PaddleOCR job API (submit, poll, download JSONL); mcp starts the
configured MCP command and discovers a formula tool; local invokes the legacy
specified PaddleOCR-VL-REC script. The optional .env.token file is accepted
as a token-only fallback for API debugging; it is the 飞桨 AI Studio access token
(see https://aistudio.baidu.com/overview), and its contents must never be
printed or committed.
Output contract
Unless the user asks for another format, deliver:
- the confirmed LaTeX and any normalization notes;
- a JSON animation document (or a link/path to one);
- the standalone
assets/math-animation.htmlview with the document loaded; - a short explanation of slots and interactions.
The implementation intentionally has no runtime npm dependency. MathJax is an optional CDN enhancement for typesetting; the editor remains usable when it is unavailable.
微信扫一扫