Ce skill couvre le calcul distant via SSH, y compris l'exécution directe et la soumission Slurm :
liste des hôtes, création de handles, exécution de commandes distantes courtes (callCommand), lecture/écriture
de documents de connaissance sur l'hôte, et le cycle de vie complet des travaux asynchrones — soumission → sauvegarde de job_id → lecture
d'instantanés non bloquants par cet ID →
récolte → tour d'analyse → publication d'artefacts.
Où s'exécute host.compute : host.compute vit UNIQUEMENT sur le noyau REPL de contrôle — exécutez
chaque exemple ci-dessous avec l'outil repl_execute (JavaScript), le même noyau qui héberge
host.mcp. Les noyaux de données python/r n'ont PAS host.compute (SSH et approbations restent en
dehors de l'espace de travail sandbox) ; l'appeler depuis une cellule python/r échouera avec host.compute is undefined.
Choisir un emplacement d'exécution
Seuls les hôtes de calcul activés pour cette session sont visibles ou appelables. Découvrez-les dans un catalogue unique ;
chaque entrée a un rôle selected ou available. Un pool sélectionné non vide est une instruction d'exécution :
exécutez le travail basé sur des outils sur un ou plusieurs hôtes sélectionnés selon les besoins du travail. Le pool n'a pas
de priorité et n'implique pas de planification multi-hôtes automatique. Si aucun hôte n'est sélectionné, choisissez parmi les
entrées disponibles. Lisez details() uniquement pour les candidats nécessitant une évaluation plus approfondie.
Ne devinez jamais et ne réutilisez jamais un identifiant de fournisseur absent du catalogue. Un utilisateur nommant un hôte désactivé ne le rend pas appelable ; expliquez qu'il doit d'abord être activé pour cette session. Si aucun hôte éligible n'est utilisable, expliquez le blocage et demandez à l'utilisateur comment procéder.
const hosts = await host.compute.listHosts()
const selectedHosts = hosts.filter((host) => host.role === 'selected')
const candidates = selectedHosts.length > 0 ? selectedHosts : hosts
Chaque élément de liste est un résumé compact avec provider_id, display_name, shape, execution_mode,
status et role
(last_probe_ok, probe_failed, ou not_probed). last_probe_ok signifie que la dernière sonde persistée
a réussi ; elle n'affirme pas une connectivité en direct. Les documents de connaissance et les instantanés de sonde de ressources sont
délibérément exclus des résultats de découverte.
Référence API
// Lister les hôtes activés de cette session en tant que catalogue compact avec rôles
const hosts = await host.compute.listHosts()
// Les noms de découverte de compatibilité restent disponibles ; les deux cachent toujours les hôtes désactivés.
const visibleHosts = await host.compute.listRegistered()
const selectedHosts = await host.compute.listPreferred()
// Créer un handle vers un hôte spécifique (pas d'appel réseau)
const c = host.compute.create('ssh:<alias>')
// Exécuter une commande distante courte (lève une exception sur approval_denied / host_unreachable / timeout)
const result = await c.callCommand('<commande shell>', '<intention en une ligne pour la carte d\'approbation>', {
loginShell: true, // défaut : true — exécute les profils de connexion, puis ~/.bashrc lisible, avant cette commande
timeoutSeconds: 60 // optionnel — l'hôte applique son propre défaut (60s) lorsqu'il est omis
})
// result → { exit_code, stdout, stderr, truncated }
// Lire les instructions d'opération persistées et l'instantané indépendant de la sonde de ressources.
// doc est toujours le texte exact sauvegardé (y compris '' avant que les instructions ne soient sauvegardées).
// probe est explicitement null lorsque cet hôte n'a jamais été sondé.
const info = await host.compute.details('ssh:<alias>', { mode: 'read' })
// Ajouter une note au document de connaissance persistant de l'hôte (écriture par agent ; limite de 32 Ko appliquée).
// Append ne modifie que doc ; il ne copie ni ne modifie jamais les observations de sonde.
await host.compute.details('ssh:<alias>', {
mode: 'append',
text: '\n## Note\nmot clé appris X le <date>'
})
// Alternativement, remplacer l'intégralité du document de connaissance de l'hôte. Relire avant de remplacer,
// surtout si vous avez ajouté ci-dessus : oldText doit correspondre exactement au document persisté.
const latest = await host.compute.details('ssh:<alias>', { mode: 'read' })
await host.compute.details('ssh:<alias>', {
mode: 'replace',
text: '<nouveau document complet>',
oldText: latest.doc
})
Traitez doc comme instructions d'opération et connaissance durable de l'hôte. Traitez probe comme une observation
datée : les valeurs des ressources peuvent changer, et la détection d'un planificateur n'autorise pas à soumettre un
travail ni à sélectionner un compte, une partition ou une file d'attente. En cas d'incompatibilité de document ou d'erreur details_conflict,
relisez et fusionnez votre brouillon avec le document le plus récent avant de réessayer. Un rafraîchissement de sonde uniquement
sur les ressources ne change pas doc et ne provoque pas de conflit de remplacement. Après avoir écrit, relisez pour vérifier
le contenu sauvegardé. Un résultat d'ajout ou de remplacement réussi est uniquement { ok: true }. Le résultat d'écriture
ne contient pas doc ou probe ; relisez toujours pour vérifier le doc exact persisté plutôt que de lire les champs
du résultat d'écriture.
Avec loginShell: true, les profils de connexion Bash distants s'exécutent d'abord, puis Open-Science tente de
trouver la source de ~/.bashrc lorsqu'elle est lisible. Un .bashrc peut délibérément retourner tôt pour les shells non interactifs,
donc les variables déclarées après une telle garde ne sont pas disponibles. Un .bashrc manquant est une opération nulle.
Définissez loginShell: false pour exécuter la commande sans aucune étape d'initialisation. Les échecs d'initialisation
sont signalés via le comportement normal de résultat/erreur de la commande.
Référence API (travaux asynchrones)
Utilisez submitJob pour les calculs de longue durée (minutes à heures). Il retourne immédiatement avec un
job_id ; le travail s'exécute sur l'hôte distant en arrière-plan. Lorsque le travail se termine, l'application
récolte automatiquement les sorties et initie un nouveau tour d'analyse si vous n'avez pas déjà lu le
résultat final. Sauvegardez le job_id exact du résultat de soumission dans votre contexte de travail ;
il n'y a intentionnellement aucune analyse historique de travaux pour le redécouvrir. Les lectures de statut et de résultat utilisent
uniquement cet ID sauvegardé et retournent des instantanés locaux non bloquants.
Pour une entrée locale, src est relatif à l'espace de travail de la session de l'agent — le même espace de travail utilisé par les outils
et outils d'écriture de fichiers. Écrivez un script ou une petite entrée générée là, puis passez son chemin relatif. Open
Science prend des instantanés des entrées acceptées avant l'approbation et l'envoi. Ne passez pas de chemins absolus locaux arbitraires
ou ne copiez pas de fichiers dans des répertoires notebooks/... gérés par l'application. Un src absolu est valide
uniquement lorsqu'il s'agit du chemin exact retourné par host.artifactPath(versionId) ou d'un chemin d'entrée de session enregistré
déjà fourni dans le contexte du notebook.
// Réutiliser les `candidates` sélectionnées ci-dessus dans le catalogue de session.
// Soumettre un travail non bloquant — retourne immédiatement après l'approbation de l'utilisateur.
// Le mode d'exécution configuré de l'hôte de calcul sélectionne SSH direct ou Slurm.
const c = host.compute.create('ssh:<alias>')
const job = await c.submitJob(
'<intention en une ligne pour la carte d\'approbation>', // affiché dans la carte d'approbation
'<commande shell>', // commande à exécuter à distance
{
environment: 'protein-gpu', // nom logique optionnel ; voir Activation d'environnement ci-dessous
timeoutSeconds: 3600, // optionnel ; défaut 24 h, max 7 jours
inputs: [
{ src: 'in.dat', dstFilename: 'in.dat' }, // mettre en scène un fichier de l'espace de travail de la session de l'agent
{ remotePath: 'ssh:<alias>/<chemin_abs>' } // lier un fichier distant (pas de transfert)
],
outputs: [
'*.result', // en vedette (visibilité par défaut)
{ glob: '*.json', visibility: 'featured' }, // explicitement en vedette
{ glob: '*.log', visibility: 'hidden' }, // masqué (diagnostic, pas affiché dans la carte)
{ glob: 'checkpoints/**', residency: 'remote' } // laisser à distance — enregistré dans left_on_remote
],
harvest: {
exclude: ['work/**'], // ne jamais récolter ces chemins
maxFileMb: 100, // maximum absolu par fichier (100 Mio)
maxTotalMb: 500 // maximum absolu par travail, y compris stdout/stderr (500 Mio)
}
}
)
// job → { job_id, provider_id, status: 'submitted' | 'queued', remote_workdir }
const savedJobId = job.job_id // conserver cet identifiant exact pour l'étape dépendante ultérieure
return { ...job, job_id: savedJobId }
Lire un instantané de travail sauvegardé
Utilisez l'ID sauvegardé lorsque l'état ou le résultat du travail est pertinent. .status() et .result() sont
des lectures locales non bloquantes dans tous les états ; ni l'un ni l'autre n'attend la fin, ne déclenche SSH, ni ne démarre une autre
récolte. .result() inclut également les listes de fichiers récoltés. Les deux appels signalent
follow_up_delivery. Une lecture finale .result() retourne suppressed lorsqu'elle empêche la repli,
ou committed lorsque ce repli a déjà franchi sa barrière d'envoi. Un instantané .status() reste
pending car il omet les listes de fichiers récoltés. Utilisez l'ID exact de la soumission plutôt que de rechercher d'anciens travaux.
const snapshot = await c.attachJob(savedJobId).result()
if (!snapshot.result_final) {
return {
job_id: savedJobId,
status: snapshot.status,
result_final: false,
follow_up_delivery: snapshot.follow_up_delivery
}
}
return snapshot
Ne considérez que result_final: true comme le résultat final. Cela signifie que la réponse automatique est prête :
success, failed et timeout peuvent encore attendre la récolte locale, tandis que cancelled et
error sont définitifs sans attendre la collecte partielle des sorties. output_files contient uniquement les fichiers
effectivement disponibles localement ; une liste vide ne prouve pas l'absence de sorties distantes.
L'application gère le polling du fournisseur et la récolte en arrière-plan. Un résultat final non lu
est délivré lors d'un tour d'agent ultérieur. Un instantané final .result() signale
follow_up_delivery: 'suppressed' lorsqu'il supprime ce repli, ou committed si la livraison automatique
a déjà gagné la course et reste faisant autorité. .status() ne consomme jamais le résultat complet.
SSH direct ou Slurm
Le mode d'exécution configuré de l'hôte de calcul sélectionne comment chaque travail est lancé. direct_ssh exécute
la commande comme un processus détaché sur la cible SSH. slurm la soumet avec sbatch ; placez les
#SBATCH directives requises du cluster en haut de command. Open-Science possède la soumission, le polling
du statut du planificateur, l'annulation et la récolte. N'appelez pas sbatch, squeue ou scancel
autour de submitJob vous-même.
Pour une erreur de statut Slurm ou une annulation échouée, lisez
Dépannage Slurm. Dans ce chemin exceptionnel,
compute.callCommand peut inspecter le même travail et ses sorties et effectuer une récupération dans le cadre de
autorisation de tâche existante de l'utilisateur. Gardez la soumission ordinaire sur l'API Compute.
Lisez listHosts() pour le mode configuré et details() pour les directives spécifiques au fournisseur ; n'essayez pas
de remplacer le mode par travail ou de l'inférer uniquement à partir de la charge de travail. Si Slurm est indisponible ou
rejette le script, signalez l'erreur retournée et
l'étape concrète suivante (par exemple, ajoutez une directive de compte ou de partition). Ne réexécutez pas silencieusement la charge de travail
directement sur un nœud de connexion.
Open-Science accepte les directives de travail uniques ordinaires telles que partition, compte, CPU, mémoire et
GPU. Définissez timeoutSeconds pour la durée d'exécution de la charge de travail. Vous pouvez définir la limite d'allocation du planificateur avec
une directive #SBATCH --time=valeur ; lorsqu'elle est absente, Open-Science dérive une limite d'allocation par défaut
à partir de timeoutSeconds. Open-Science possède le nom du travail, le répertoire de travail, stdout et stderr
directives. Évitez les tableaux de travaux car un travail Open-Science suit un travail planificateur et une
récolte de sortie. Soumettez les travaux indépendants comme des travaux séparés et utilisez la limite de concurrence de session lorsque
c'est nécessaire.
Pour Slurm, demandez des ressources avec une directive #SBATCH --option=valeur par ligne (ou un indicateur sans valeur
tel que #SBATCH --exclusive). L'option resources héritée est des métadonnées descriptives ; elle
n'alloue pas de CPU, mémoire ou GPU. timeoutSeconds limite la durée d'exécution de la charge de travail, pas l'attente dans la file ;
#SBATCH --time définit la limite d'allocation du planificateur. Aucun des deux n'est une promesse de temps de démarrage dans la file.
Les instantanés non bloquants de status() et result() du travail incluent scheduler_job_id lorsqu'il est connu,
error: { code, message } en cas d'erreur au niveau du travail, et last_poll_error lorsque l'observation ou la récupération de soumission nécessite
de l'attention. Une raison en attente ou une ligne de comptabilité retardée ne signifie pas que la charge de travail a échoué. Si une
soumission n'est pas confirmée, utilisez l'identité de travail signalée et les diagnostics du fournisseur avant de décider
si vous devez soumettre à nouveau ; Open-Science ne soumet pas automatiquement un doublon.
Activation d'environnement
La valeur optionnelle environment est un nom logique, pas une commande shell. Open-Science sourcr
~/.open-science/environments/<nom>.sh avant la charge de travail pour les travaux directs et Slurm. Les noms sont
de 1 à 64 lettres, chiffres, points, underscores ou traits d'union et doivent commencer par une lettre ou un chiffre.
Le fichier et chaque chemin de logiciel/cache qu'il référence doivent être visibles sur le nœud d'exécution.
Si une soumission signale que ce fichier d'activation est manquant, chargez le Skill de Configuration d'Environnement Compute
pour préparer des instructions exactes de configuration, réparation et suppression pour l'utilisateur ou l'administrateur de l'hôte
à exécuter en dehors d'Open-Science. Validez l'activation gérée par l'utilisateur après qu'il applique le plan, puis
réessayez. Ne devinez pas un nom conda, n'ajoutez pas d'installation en ligne au travail scientifique, et ne cachez pas l'activation dans
.bashrc. Omettez environment lorsque la commande utilise délibérément l'environnement par défaut de l'hôte.
Limites de sécurité de la récolte
- Les fichiers de sortie déclarés sont sélectionnés avant
stdoutetstderr; les journaux utilisent le budget restant par travail. - L'application rejette les limites fournies par le modèle supérieures à 100 Mio par fichier ou 500 Mio par travail.
- La récolte préserve également un espace disque local libre fixe de 2 Gio. Les fichiers qui ne tiennent pas restent distants.
Limites de comportement
- Pendant que le travail s'exécute : la conversation est ouverte. L'utilisateur peut envoyer des messages ; vous pouvez gérer d'autres tâches. Chaque requête de statut/résultat retourne immédiatement avec l'instantané local actuel.
- Lorsque le travail se termine : si vous n'avez pas activement lu son résultat final, l'application initie un nouveau tour d'analyse automatiquement. Vous ne déclenchez pas ce repli.
Vérifier le statut du travail (lecture non bloquante, à des fins informatives)
// Lecture DB non bloquante — pas de SSH. Utilisez-la si vous avez besoin d'un instantané de statut en cours de conversation.
const handle = c.attachJob(job.job_id)
const s = await handle.status()
// s → {
// job_id, scheduler_job_id?, status, result_final, cancellation?, exit_code,
// error?, last
…
[tronqué pour la traduction]