Working with Dependencies
NeuroScript packages can depend on other packages distributed as git repositories or local directories. The dependency system handles fetching, caching, version locking, and integration with the compiler.
Adding Dependencies
Use neuroscript add to declare a dependency in your Axon.toml:
Git Dependencies
# Add from a git repository
neuroscript add attention-blocks \
--git "https://github.com/user/attention.git"
# Pin to a specific branch
neuroscript add attention-blocks \
--git "https://github.com/user/attention.git" \
--branch main
# Pin to a tag
neuroscript add attention-blocks \
--git "https://github.com/user/attention.git" \
--tag v0.2.0
# Pin to a specific commit
neuroscript add attention-blocks \
--git "https://github.com/user/attention.git" \
--rev abc123
Path Dependencies
For local development, reference packages by filesystem path:
neuroscript add local-utils --path ../local-utils
Path dependencies are resolved relative to your project root. They are useful when developing multiple packages together.
Version Dependencies
For future registry support:
neuroscript add core-primitives --version "^1.0"
Resulting Axon.toml
After adding dependencies, your manifest will look like:
[dependencies]
attention-blocks = { git = "https://github.com/user/attention.git", branch = "main" }
local-utils = { path = "../local-utils" }
core-primitives = "^1.0"
Fetching Dependencies
Run neuroscript fetch to download all declared dependencies:
neuroscript fetch
Fetching 2 dependencies...
✓ attention-blocks -> /Users/you/.neuroscript/git/a1b2c3
✓ local-utils -> /Users/you/projects/local-utils
✓ Generated Axon.lock
✓ All dependencies fetched successfully
Use --verbose for detailed output, or --update to pull the latest compatible versions:
neuroscript fetch --verbose
neuroscript fetch --update
Where Dependencies Go
- Git dependencies are cloned to
~/.neuroscript/git/<hash>/ - Path dependencies are resolved in place (no copying)
- A shared cache at
~/.neuroscript/avoids redundant clones
The Lockfile (Axon.lock)
After fetching, an Axon.lock file is generated that pins exact versions and commit hashes:
# This file is @generated by neuroscript
# It is not intended for manual editing
version = 1
[[package]]
name = "attention-blocks"
version = "0.3.1"
source = "git+https://github.com/user/attention.git?rev=abc123"
[[package]]
name = "local-utils"
version = "0.1.0"
source = "path+/Users/you/projects/local-utils"
Commit your lockfile to version control. This ensures everyone on your team builds with the exact same dependency versions.
Using Neurons from Dependencies
Once dependencies are fetched, import their neurons using use statements in your .ns files:
Wildcard Import
Import all exported neurons from a package:
use attention-blocks,src/*
neuron MyModel(dim, heads):
in: [*batch, seq, dim]
out: [*batch, seq, dim]
graph:
in -> MultiHeadAttention(dim, heads) -> out
Specific Import
Import a single neuron by name:
use attention-blocks,src/CrossAttention
neuron DecoderBlock(dim, heads):
in: [*batch, seq, dim]
out: [*batch, seq, dim]
graph:
in -> CrossAttention(dim, heads) -> out
Multiple Imports
use attention-blocks,src/*
use local-utils,src/*
neuron FullModel(dim, heads, expansion):
in: [*batch, seq, dim]
out: [*batch, seq, dim]
graph:
in ->
MultiHeadAttention(dim, heads)
SwiGLU_FFN(dim, expansion)
out
Integration with Compile and Validate
The compiler automatically loads dependencies when an Axon.lock file is present:
# Validates with all dependency neurons available
neuroscript validate src/model.ns
# Compiles with dependency neurons in scope
neuroscript compile src/model.ns
# Skip dependency loading (useful for standalone files)
neuroscript validate src/model.ns --no-deps
neuroscript compile src/model.ns --no-deps
The compiler walks up from your input file to find the nearest Axon.lock, then loads all declared dependencies into the symbol table before validation and compilation.
Merge Precedence
When the same neuron name exists in multiple sources, precedence is:
- User-defined neurons (your
.nsfiles) - highest priority - Standard library neurons
- Dependency neurons - lowest priority
This means you can override any dependency or stdlib neuron by defining one with the same name in your project.
Discovering Available Neurons
Use the list command to explore what neurons are available:
# List all stdlib primitives and composites
neuroscript list --stdlib
# List neurons from a specific dependency
neuroscript list --package attention-blocks
# List everything: stdlib + all dependencies
neuroscript list --available
# List neurons defined in a file
neuroscript list src/model.ns
Full Workflow Example
Here's a complete example of consuming a package:
# 1. Initialize your project
neuroscript init my-model --author "You <[email protected]>"
cd my-model
# 2. Add a dependency
neuroscript add transformer-blocks \
--git "https://github.com/user/transformer-blocks.git"
# 3. Fetch it
neuroscript fetch
# 4. See what neurons are available
neuroscript list --available
5. Write your model using imported neurons in src/my_model.ns:
use transformer-blocks,src/*
neuron MyLanguageModel(dim, heads, layers, vocab):
in: [*batch, seq]
out: [*batch, seq, vocab]
graph:
in ->
Embedding(vocab, dim)
PreNormBlock(dim, heads, 4)
PreNormBlock(dim, heads, 4)
PreNormBlock(dim, heads, 4)
LayerNorm(dim)
Linear(dim, vocab)
out
6. Validate and compile:
neuroscript validate src/my_model.ns
neuroscript compile src/my_model.ns -o model.py
The compiled Python module will include all necessary imports for both your neurons and the dependency neurons used in the graph.