Imports multi-modules
Les imports permettent de relier explicitement plusieurs modules Touba dans un projet local.
Touba couvre ces imports dans un même projet :
type;definenon sensible ;functionpure ;toollocal ;skill;strategy;agentaveccallable_byexplicite ;memorylogique avec scopes explicites.
Les imports ne donnent aucune autorité d’exécution. Ils n’ajoutent pas de grant, de secret, de scope mémoire, de handler ou de manifest.
Les champs des types importés et les signatures des fonctions sont résolus
avant le typage des expressions. Vous pouvez lire request.query, réutiliser
un résultat dans une expression et fournir les arguments par leur nom, sans
annotation de contournement. Les types restent nominaux : deux déclarations
homonymes dans des modules différents ne deviennent pas interchangeables.
Avec touba prepare, conservez les sources sous src/<nom/du/module>.tb et
déclarez les packages utilisés dans le projet. Un import absent, incompatible
ou non exporté est une erreur ; il ne crée pas un contrat implicite.
Syntaxe
Forme :
import type Name from module.name
import define Name from module.name
import function Name from module.name
import tool Name from module.name
import skill Name from module.name
import strategy Name from module.name
import agent Name from module.name
import memory Name from module.name
Les imports se placent après module et avant les autres déclarations du fichier.
Exemple :
module examples.search
import type SearchRequest from examples.common
import define DefaultRows from examples.common
import function NormalizeQuery from examples.common
Exemple de projet
Imports purs
Module commun :
module examples.common
type SearchRequest
query is Text
rows is Int
define DefaultRows as Int = 5
function NormalizeQuery
takes query as Text
gives Text
do
give query
Module importeur :
module examples.search
import type SearchRequest from examples.common
import define DefaultRows from examples.common
import function NormalizeQuery from examples.common
strategy RunSearch
gives Text
do
show
with message as "search project ready"
give "done"
Commande :
touba prepare --mode write
Résultat attendu :
- l’AIR préparé du projet contient les imports déclarés ;
- les imports sont résolus par l’assemblage projet ;
- aucun manifest ni handler n’est créé si le projet ne déclare pas de
tool; touba inspectpeut afficher les imports et leur statut ;- l’extension VS Code peut afficher hover, symboles, navigation et diagnostics liés aux imports.
Import local de tool
Module déclarant :
module examples.data_tools
type DatasetSearchRequest
query is Text
rows is Int
type DatasetSearchResult
title is Text
url is Text
tool SearchDatasets
takes request as DatasetSearchRequest
gives DatasetSearchResult
requires network
Module importeur :
module examples.research_app
import type DatasetSearchRequest from examples.data_tools
import type DatasetSearchResult from examples.data_tools
import tool SearchDatasets from examples.data_tools
skill BuildDatasetBrief
takes request as DatasetSearchRequest
gives DatasetSearchResult
uses SearchDatasets
do
SearchDatasets
with request as request
into result
give result
Après touba prepare --mode write :
- l’AIR préparé du module importeur contient l’import de
toolrésolu ; - la référence du tool reste
tool:examples.data_tools/SearchDatasets; - le binding de manifest vise cette référence canonique ;
- le stub de handler est rattaché au module déclarant, par exemple
handlers/examples/data_tools/search_datasets.handler.mjs; - l’import ne crée aucun grant implicite :
requires networkdoit rester accordé par le manifest.
Import de skill et strategy
Module partagé :
module examples.shared_flow
skill NormalizeTopic
takes topic as Text
gives Text
do
bind normalized as Text = "topic:" ++ topic
give normalized
strategy SharedTopicRun
takes topic as Text
gives Text
uses NormalizeTopic
do
NormalizeTopic
with topic as topic
into normalized
give normalized
Module importeur :
module examples.flow_app
import skill NormalizeTopic from examples.shared_flow
import strategy SharedTopicRun from examples.shared_flow
strategy RunImportedSkill
takes topic as Text
gives Text
uses NormalizeTopic
do
NormalizeTopic
with topic as topic
into normalized
give normalized
Résultat attendu :
- le skill importé garde la référence
skill:examples.shared_flow/NormalizeTopic; - la strategy importée garde la référence
strategy:examples.shared_flow/SharedTopicRun; - l’AIR préparé inclut les graphes nécessaires ;
- aucun handler ou manifest n’est créé si le flux n’appelle pas de
tool.
Import d’agent
Le compilateur résout la signature explicite de l'agent dans son module source.
Le module importeur utilise les mêmes with / into qu'un appel local.
L'agent reste fermé par défaut : son module nomme les callers autorisés.
module examples.agent_pool
function PrepareReview
description "Return the supplied review text."
takes brief as Text
gives Text
do
give brief
agent Reviewer
takes brief as Text
gives Text
responsibility "Return the review through the declared capability."
uses PrepareReview
callable_by strategy examples.agent_app.RunReview
module examples.agent_app
import agent Reviewer from examples.agent_pool
strategy RunReview
takes brief as Text
gives Text
uses Reviewer
do
Reviewer
with brief as brief
into reviewed
give reviewed
examples.agent_app.RunReview est le caller qualifié, pas un droit accordé
au module entier. Compiler depuis la racine du projet avec les deux modules
présents. Une signature compatible ne dispense pas de callable_by ; les
types importés conservent leur identité de module. Une même invocation typée
peut aussi être la cible d'un groupe parallel dans une stratégie autorisée.
Import de memory logique
Une mémoire importée reste une ressource logique. Elle ne crée pas de backend et ne donne aucun accès par elle-même.
module examples.shared_memory
memory ProjectKnowledge
module examples.memory_tools
import memory ProjectKnowledge from examples.shared_memory
type KnowledgeQuery
query is Text
type KnowledgeResult
summary is Text
tool ReadKnowledge
takes query as KnowledgeQuery
gives KnowledgeResult
requires memory_read
uses memory ProjectKnowledge read
module examples.memory_app
import type KnowledgeQuery from examples.memory_tools
import type KnowledgeResult from examples.memory_tools
import memory ProjectKnowledge from examples.shared_memory
import tool ReadKnowledge from examples.memory_tools
skill BuildKnowledgeAnswer
takes query as KnowledgeQuery
gives KnowledgeResult
uses ReadKnowledge
memory ProjectKnowledge read
do
ReadKnowledge
with query as query
into result
give result
Résultat attendu :
- la mémoire garde la référence
memory:examples.shared_memory/ProjectKnowledge; - le tool d’accès garde
uses memory ... read; - le skill doit déclarer
memory ProjectKnowledge read; - le manifest doit accorder le binding, les grants et les éventuels secrets du handler ;
- sans scope côté owner, le projet est refusé.
Inspection
Après prepare, inspecter l’AIR produit :
touba inspect .touba/air/examples/search.air.json
Sortie attendue, en substance :
imports=3 resolved=3 unresolved=0
import type SearchRequest from examples.common -> type:examples.common/SearchRequest
import define DefaultRows from examples.common -> define:examples.common/DefaultRows
import function NormalizeQuery from examples.common -> function:examples.common/NormalizeQuery
Le détail exact dépend du mode de sortie, mais les informations importantes sont :
- le type d’import ;
- le nom importé ;
- le module source ;
- la référence AIR canonique ;
- le statut résolu ou refusé.
Refus importants
Touba refuse les imports qui ouvriraient une autorité implicite ou une ambiguïté de nom.
Exemples de refus :
import function NormalizeQuery from examples.common
function NormalizeQuery
takes query as Text
gives Text
do
give query
Refus attendu : collision de nom entre import et déclaration locale.
import * from examples.common
Refus attendu : les imports wildcard ne sont pas acceptés.
Un agent importé sans règle callable_by compatible est également refusé. Un
tool importé sans grant, secret ou binding attendu sera refusé au runtime avant
handler.
Contrat D’import
Les imports purs (IM-1) couvrent la partie pure du partage multi-modules :
type, define non sensible et function pure. Les imports effectifs (IM-2) ajoutent les composants effectifs locaux
tool, skill, strategy, agent et memory, sans déplacer l’autorité
runtime.
Le contrat d’import est explicite par conception :
- pas de résolution de packages externes ou registry dans ce mécanisme projet local ;
- pas d’alias, wildcard ou re-export ;
- pas d’ajout implicite de grant, secret, scope mémoire, caller d’agent, manifest ou handler ;
- pas de résolution d’import côté runtime ;
- pas de backend mémoire déduit depuis
memory; - pas d’autorisation par module entier.
Ces frontières évitent qu’un import ajoute silencieusement un grant, un secret, un scope mémoire, un caller d’agent, un package ou un point d’entrée runtime. Les packages et le registry conservent la même règle : rendre un composant disponible sans lui accorder d’autorité d’exécution.
Les signatures d'agents et de stratégies importés sont résolues avant les
appels typés, y compris les cibles parallel. Les énumérations s'importent
avec import type ; listes, records et optionnels conservent les types nominaux
de leurs modules. Les sources doivent être disponibles au compilateur :
l'import ne découvre jamais un handler ni un droit à l'exécution.