name: protein-mutation-enhancement description: > Deterministic protein gain-of-function mutation workflow: build single, double, and higher-order mutant libraries; merge ESM sequence-effect scores, structure metrics from ESMFold-class models, property/function scores; rank candidates; and decide whether to stop or start the next design round. origin: openai4s category: workflow requirements: [gpu] capabilities: network: mode: none domains: []
Use this skill when the task is to improve a target protein by iterative
mutation design. It is an orchestration layer: deterministic library
construction, score merging, ranking, and loop-control run locally with
stdlib-only helpers; heavyweight model calls run through existing model skills
such as fair-esm2 and esmfold2.
A12V+G47D.fair-esm2 or esmfold2 for concrete GPU recipes;id, commonly with esm_delta where higher is
better.esmfold2 for ESMFold2 / ESMFold2-Fast recipes;id, commonly plddt, ptm, pae,
rmsd_to_wt, or task-specific interface metrics.host.submit_output(...). If none
pass, use the top ranked variants to seed the next loop and expand the
library.The directory name contains hyphens, so import via importlib:
import importlib
pm = importlib.import_module("protein-mutation-enhancement.kernel")
wt = "MKTAYIAKQRQISFVKSHFSRQ"
library = pm.enumerate_mutants(
wt,
positions=[3, 5, 8, 12],
substitutions={3: ["A", "L", "F"], 5: ["V", "L"], 8: ["R", "K"]},
max_order=2,
limit=500,
)
pm.write_fasta(library, "round1_mutants.fasta")
positions are 1-indexed. If substitutions omits a position, all 20 natural
amino acids except the wild-type residue are used. Candidate IDs are stable and
sorted by position, so downstream score tables can safely join on id.
After running ESM and structure jobs, load or construct score tables keyed by variant ID:
esm_scores = {
"T3L": {"esm_delta": 1.8},
"Y5V": {"esm_delta": 0.3},
"T3L+Y5V": {"esm_delta": 2.1},
}
structure_scores = {
"T3L": {"plddt": 86.0, "rmsd_to_wt": 0.8},
"Y5V": {"plddt": 71.0, "rmsd_to_wt": 2.4},
"T3L+Y5V": {"plddt": 82.0, "rmsd_to_wt": 1.1},
}
round_result = pm.run_selection_round(
library,
score_tables=[esm_scores, structure_scores],
weights={
"esm_delta": 0.45,
"plddt": 0.25,
"rmsd_to_wt": 0.15,
"property_score": 0.15,
},
directions={"rmsd_to_wt": "low"},
acceptance_thresholds={
"composite_score": 0.72,
"esm_delta": 1.0,
"plddt": 75.0,
},
top_k=20,
)
best = round_result["ranked"][0]
print(best["id"], best["composite_score"], round_result["should_continue"])
property_score is computed locally from conservative amino-acid-class,
hydropathy, charge, and size-change heuristics unless an external table
provides it. External assay or task-proxy metrics can be added as extra columns
and weights.
current_library = pm.enumerate_mutants(wt, positions=active_positions, max_order=1)
for round_idx in range(1, 6):
# 1. Score `current_library` using fair-esm2 / ESMC.
# 2. Fold the promising subset using esmfold2 / ESMFold2-Fast.
# 3. Merge the resulting tables.
result = pm.run_selection_round(
current_library,
score_tables=[esm_scores, structure_scores, function_scores],
weights=weights,
directions=directions,
acceptance_thresholds=thresholds,
top_k=50,
)
if not result["should_continue"]:
host.submit_output({"accepted": result["accepted"], "round": round_idx})
break
active_positions = pm.suggest_next_positions(result["ranked"], max_positions=10)
current_library = pm.enumerate_mutants(
wt,
positions=active_positions,
max_order=min(round_idx + 1, 4),
seeds=result["next_round_seeds"],
limit=2000,
)
else:
host.submit_output({"accepted": [], "ranked": result["ranked"][:20]})
max_order=1 for the first pass, then expand top single mutants into
doubles/combinations with seeds=....mutants.fastaesm_scores.csvstructure_scores.csvranked_candidates.jsonfair-esm2, esmfold2) and compute skills.