Tool Calling & Lazy Loading
This guide explains how AgentOS wires extensions (tools) and skills (prompt modules) into a tool-calling agent loop, and what “lazy loading” means in practice.
Tool Calling Loop (Runtime)
At a high level, each turn looks like:
Key implementation points:
ToolOrchestrator.listAvailableTools()returns the tool schemas the model can call this turn.ToolOrchestrator.processToolCall()enforces permissions and delegates execution toToolExecutor.ToolExecutorresolves tools from the toolExtensionRegistryby tool-call name (ITool.name).
Extensions: How Tools Load
AgentOS loads extension packs from extensionManifest.packs via ExtensionManager.loadManifest() and registers descriptors into kind-specific registries.
Pack Resolution Modes
AgentOS supports three ways to resolve a pack entry:
factory: inline factory returning anExtensionPackpackage: dynamicimport()of an npm package exportingcreateExtensionPack()module: dynamicimport()of a local module path exportingcreateExtensionPack()
Descriptor IDs For Tools
Tool calling uses the OpenAI-style tool name, which maps to ITool.name.
For tool descriptors, keep:
descriptor.id === tool.name
Secrets & Required Secrets
Descriptors can declare requiredSecrets. AgentOS resolves secrets from:
- explicit
extensionSecrets(host-provided), plus packs[].options.secrets(if provided), plus- environment variables mapped via the extension secrets catalog (
extension-secrets.json)
If a descriptor declares a non-optional secret and it can’t be resolved, it’s skipped.
Skills: Prompt Modules + Optional Tooling
Skills are prompt modules loaded from SKILL.md files. Hosts can inject skills into a system prompt via SkillRegistry.buildSnapshot().
For “lazy” skills, load the @framers/agentos-ext-skills extension pack so the model can fetch SKILL.md content on demand (via tool calls) instead of pre-injecting everything.
What “Lazy Loading” Means Here
AgentOS supports a few different “lazy” patterns:
- Lazy optional dependencies: registry helpers can
tryImport()optional extension packages and skip those not installed. - Lazy pack import:
package/moduleentries are imported whenloadManifest()runs. - Lazy tool implementation: a tool’s
execute()can dynamicallyimport()heavy dependencies on first call.
Schema-On-Demand Tool Schemas (Optional)
Tool calling still requires schemas up front for each round. However, AgentOS now supports a schema-on-demand pattern via optional meta tools that can load extension packs at runtime.
When enabled, AgentOS registers these meta tools:
extensions_list— list loaded packs + curated catalog (if installed)extensions_enable— load an extension pack at runtime (side effects, HITL recommended)extensions_status— show packs loaded in this process
Because the GMI loop calls ToolOrchestrator.listAvailableTools() on every iteration, any tools added by extensions_enable appear in the next LLM call’s tool schemas automatically.
How To Enable In AgentOS
In AgentOSConfig, set:
schemaOnDemandTools: {
enabled: true,
// Recommended for production: allow curated names only (no arbitrary package imports).
// Default: true in non-production, false in production.
allowPackages: false,
// Default: false (prefer curated packages).
allowModules: false,
// Default: true. When enabled, `extensions_enable` only loads packs present in
// the installed @framers/agentos-extensions-registry catalog.
officialRegistryOnly: true,
}
Then start your agent with a minimal extensionManifest (or selectively-loaded packs), and let the model call extensions_enable as needed.