Skip to main content
Version: 1.0.0

Multi-Module Imports

Imports explicitly connect several Touba modules inside a local project.

Touba covers these imports within one project:

  • type;
  • non-sensitive define;
  • pure function;
  • local tool;
  • skill;
  • strategy;
  • agent with explicit callable_by;
  • logical memory with explicit scopes.

Imports grant no execution authority. They add no grant, secret, memory scope, handler, or manifest.

Imported fields and function signatures are resolved before expression typing. You can read request.query, reuse a result in an expression and supply named arguments without workaround annotations. Types remain nominal: declarations with the same name in different modules are not interchangeable.

With touba prepare, keep sources under src/<module/name>.tb and declare the packages used by the project. Missing, incompatible or unexported imports are errors; they never create implicit contracts.

Syntax​

Shape:

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

Imports are placed after module and before the other declarations in the file.

Example:

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

Project Example​

Pure Imports​

Shared module:

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

Importing module:

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"

Command:

Terminal
touba prepare --mode write

Expected result:

  • the prepared project AIR contains the declared imports;
  • imports are resolved by project assembly;
  • no manifest or handler is created when the project declares no tool;
  • touba inspect can display imports and their status;
  • the VS Code extension can display hover, symbols, navigation, and diagnostics related to imports.

Local Tool Import​

Declaring module:

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

Importing module:

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

After touba prepare --mode write:

  • the prepared AIR for the importing module contains the resolved tool import;
  • the tool reference remains tool:examples.data_tools/SearchDatasets;
  • the manifest binding targets this canonical reference;
  • the handler stub is attached to the declaring module, for example handlers/examples/data_tools/search_datasets.handler.mjs;
  • the import creates no implicit grant: requires network must still be granted by the manifest.

Skill and Strategy Import​

Shared module:

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

Importing module:

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

Expected result:

  • the imported skill keeps reference skill:examples.shared_flow/NormalizeTopic;
  • the imported strategy keeps reference strategy:examples.shared_flow/SharedTopicRun;
  • the prepared AIR includes the required graphs;
  • no handler or manifest is created if the flow calls no tool.

Agent Import​

The compiler resolves the agent's explicit signature from its source module. The importer uses the same named with inputs and into output as a local call. The agent remains closed by default: its module names authorized callers.

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 is a qualified caller, not module-wide authority. Compile from the project root with both modules present. A compatible signature does not bypass callable_by; imported types retain their module identities. A typed imported agent can also be a parallel target in an authorized strategy.

Logical Memory Import​

An imported memory remains a logical resource. It does not create a backend and grants no access by itself.

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

Expected result:

  • the memory keeps reference memory:examples.shared_memory/ProjectKnowledge;
  • the access tool keeps uses memory ... read;
  • the skill must declare memory ProjectKnowledge read;
  • the manifest must grant the binding, grants, and any handler secrets;
  • without an owner-side scope, the project is refused.

Inspection​

After prepare, inspect the produced AIR:

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

Expected output, in substance:

Summary
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

The exact detail depends on the output mode, but the important information is:

  • import kind;
  • imported name;
  • source module;
  • canonical AIR reference;
  • resolved or refused status.

Important Refusals​

Touba refuses imports that would open implicit authority or name ambiguity.

Refusal examples:

source.tb
import function NormalizeQuery from examples.common

function NormalizeQuery
takes query as Text
gives Text
do
give query

Expected refusal: name collision between import and local declaration.

source.tb
import * from examples.common

Expected refusal: wildcard imports are not accepted.

An imported agent without a compatible callable_by rule is also refused. An imported tool without an expected grant, secret, or binding is refused by the runtime before the handler.

Import Contract​

Pure imports (IM-1) cover the pure part of multi-module sharing: type, non-sensitive define, and pure function. Effectful imports (IM-2) add local effectful components: tool, skill, strategy, agent, and memory, without moving runtime authority.

The import contract is explicit by design:

  • no external packages or registry resolution in this local-project mechanism;
  • no aliases, wildcards, or re-exports;
  • no implicit grant, secret, memory scope, agent caller, manifest, or handler;
  • no runtime-side import resolution;
  • no memory backend inferred from memory;
  • no module-wide authorization.

These boundaries keep imports from silently adding grants, secrets, memory scopes, agent callers, packages, or runtime entry points. Packages and the registry preserve the same rule: make a component available without granting execution authority.

Imported agent and strategy signatures are resolved before typed calls, including parallel targets. Import enums with import type; lists, records and optionals retain the nominal identity of their module-defined types. Source modules must be available to the compiler: imports never discover handlers or grant authority.