Use this skill for technical model construction and editing through the SDK. Keep the scope on SDK mechanics and model validity, not biological plausibility.
Core Rules
- Prefer editing an existing model over recreating a model from scratch.
- Start a new model only when the user explicitly needs one, using
client.create_empty_model(). - Favor high-level component methods; do not build raw model payloads unless the typed SDK surface cannot express the requested edit.
- Favor
model.components.batch(version_name=...)for component changes so related edits are committed as one model version. - Treat a complete model as one with no error-level diagnostics and a successful
simple_solve()for relevant outputs. - Report diagnostics or solve errors clearly and ask whether the user wants them fixed.
Project Folder Hygiene
- Prefer creating models inside a dedicated Jinkō folder instead of the project root. At the start of a workflow, ask for or propose a folder name, for example
YYYY-MM-DD-<experiment-name>. - Reuse an existing exact-match folder when possible:
client.folders.get_by_name(name, exact_match_only=True). - If the folder does not exist, create it only after user confirmation or when a script is run with
--apply. - Resolve one folder object or folder id, then pass
folder=folderto SDK creation calls that support it.
Default Workflow
- Load credentials and construct
JinkoClient(). - If the user has a model SID, retrieve it with
client.get_model("<model-sid>"). - If the user needs a new model, create an empty model, then add components in a batch.
- Set solving options intentionally, especially
unitCheck. - Stage component changes with
model.components.batch(version_name="..."). - Re-fetch the model after edits if you need fresh diagnostics or solving behavior.
- Check diagnostics with
model.get_diagnostics().errors(). - Check solvability with
model.simple_solve(timeseries_ids=[...]), usingmodel.time_dependent_ids()as the default candidate outputs when the user has not specified ids. - If the default
simple_solvecandidates exceed 10 ids, preselect the first 10 returned bymodel.time_dependent_ids()and ask the user to confirm or adjust the selection before solving.
Example Scripts
Use scripts rather than embedding long Python snippets in chat.
scripts/create_minimal_model.py: creates a small model from an empty model when run with--apply.scripts/edit_existing_model_batch.py: applies a batch edit template to an existing model when run with--apply.scripts/validate_model_readiness.py: checks diagnostics andsimple_solve()for an existing model.
Examples:
python skills/jk-model/scripts/create_minimal_model.py --name sdk-minimal-model
python skills/jk-model/scripts/create_minimal_model.py --name sdk-minimal-model --apply
python skills/jk-model/scripts/create_minimal_model.py --name sdk-minimal-model --folder 2026-06-15-pk-study --create-folder --apply
python skills/jk-model/scripts/edit_existing_model_batch.py --model-sid cm-... --apply
python skills/jk-model/scripts/validate_model_readiness.py --model-sid cm-...
python skills/jk-model/scripts/validate_model_readiness.py --model-sid cm-... --timeseries-id Drug
Formula Syntax
- Piecewise formulas use ternary syntax:
condition ? value_if_true : value_if_false. - Categorical switches use case syntax:
case ID of { value1 -> expr1; value2 -> expr2; _ -> fallback }. - Event
time_trigger_*expressions need time dimension, for example0 * u(h)or1 * u(day). - Recurrent events (for regular doses) use
time_trigger_first_timeplustime_trigger_every, and optionallytime_trigger_countortime_trigger_until. - ODE right-hand sides are rates. Under unit checking, multiply by an inverse-time unit when the expression is otherwise dimensionless.
Algebraic Rules
Use create_algebraic_rule() or edit_algebraic_rule() for implicit constraints and cyclic dependencies. Jinkō algebraic rules are residual equations: the equation value is interpreted as 0 = equation.
Convert explicit implicit definitions into residual form:
x1 = f1(x1, x2)becomesf1(x1, x2) - x1.x2 = f2(x1, x2)becomesf2(x1, x2) - x2.
Add one algebraic rule per residual equation. If diagnostics report TOO_FEW_ALGEBRAIC_RULES, TOO_MANY_ALGEBRAIC_RULES, or MISSING_UNKNOWN, check that the number of algebraic equations matches the number of unknown algebraic variables.
Units Policy
- Read
references/unit_docs.mdbefore advising on non-trivial units or conversion behavior. - Use
references/units_static_info.jsonas the default allowed-unit registry before introducing non-trivial units or aliases. - Refresh unit registry data from
/core/v2/static/units/static_infoonly if the local registry is stale or insufficient. - Set
unitCheckintentionally and tell the user which mode was selected. - Prefer
UnitCheckAndConvertAllSpeciesToExtentUnitsfor new SDK-created models unless the user has a reason to choose another mode.
Available unit-check modes:
NoUnitCheckUnitCheckWithNoUnitConversionUnitCheckAndConvertAllSpeciesToExtentUnitsUnitCheckAndConvertOnlyReactantsAndProductsToExtentUnits
Solving times policy
- Jinko solving time options must stay within a 10..1000 time points.
- Number of points is
(tMax - tMin) / tStep + 1. - If
TOO_MANY_TIMEPOINTSoccurs, increase step size. - First-pass heuristic:
- compute
tStep_sec = (tMax_sec - tMin_sec) / 100, - convert to canonical ISO8601/Jinko duration using
duration_from_secsfromscripts/iso8601.py - round down to first non-null unit using
round_duration_down_to_full_unit
- compute
Reference Routing
- Read
references/model-components.mdfor component batching examples and method names. - Read
references/model-validation.mdfor diagnostics andsimple_solve()readiness checks. - Read
references/unit_docs.mdfor unit semantics.