Aller au contenu principal
Version: 1.0.0

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 ;
  • define non sensible ;
  • function pure ;
  • tool local ;
  • skill ;
  • strategy ;
  • agent avec callable_by explicite ;
  • memory logique 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 :

source.tb
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 :

src/examples/search.tb
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 :

src/examples/common.tb
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 :

src/examples/search.tb
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 :

Terminal
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 inspect peut 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 :

src/examples/data_tools.tb
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 :

src/examples/research_app.tb
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 tool ré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 network doit rester accordé par le manifest.

Import de skill et strategy​

Module partagé :

src/examples/shared_flow.tb
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 :

src/examples/flow_app.tb
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.

src/examples/agent_pool.tb
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
src/examples/agent_app.tb
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.

src/examples/shared_memory.tb
module examples.shared_memory

memory ProjectKnowledge
src/examples/memory_tools.tb
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
src/examples/memory_app.tb
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 :

Terminal
touba inspect .touba/air/examples/search.air.json

Sortie attendue, en substance :

Résumé
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 :

source.tb
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.

source.tb
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.