The @astack-tech/core package provides the foundational abstractions and execution infrastructure for the AStack framework. It is the base dependency for all other AStack packages and exports three primary abstractions:
| Export | Type | Purpose |
|---|---|---|
Component | Class | Base class for all data processing units |
Pipeline | Class | Workflow orchestration and execution engine |
Port | Static utility | Input/output port creation (via Component.Port) |
Package Location: packages/core/ in the monorepo
Key Characteristics:
@hlang-org/runtime@astack-tech/components, @astack-tech/tools, and @astack-tech/integrationsFor built-in components like Agent and TextSplitter, see page 4.2. For model provider integrations, see page 4.3. For the tool system, see page 4.4.
Sources: pnpm-lock.yaml73-96 packages/core/src/component/index.ts1-40 packages/core/src/pipeline/index.ts1-189
The core package has a single runtime dependency:
Dependency Specification: pnpm-lock.yaml75-77
The @hlang-org/runtime package provides:
Node - Base class for graph verticesTransformNode - Reactive data transformation nodeFlow - Execution engine for component graphsPort - Typed connection interface (Port.I() and Port.O())The core package extends Hlang runtime primitives with AStack-specific semantics:
Key Design Decisions:
Component extends TransformNode to provide both run() (standalone) and _transform() (pipeline) execution modesPipeline uses Flow internally but hides the complexity through a simplified APIPort is re-exported as Component.Port for convenient accessBaseProducer, BaseConsumer) manage pipeline boundaries transparentlySources: packages/core/src/component/index.ts1-40 packages/core/src/pipeline/index.ts1-6 pnpm-lock.yaml73-96
The Component class is the fundamental building block of AStack applications. All AStack components—from simple text processors to complex agents—inherit from this base class.
Key Characteristics:
| Feature | Description |
|---|---|
| Base Class | Extends TransformNode from @hlang-org/runtime |
| Port System | Exposes Port.I() and Port.O() for defining inputs/outputs |
| Default Ports | Every component has inPort and outPort by default |
| Dual Execution | Supports both run() (standalone) and _transform() (pipeline) modes |
Sources: packages/core/src/component/index.ts1-40
Components use the Port abstraction to define typed input and output interfaces. Ports are the connection points that enable components to send and receive data.
Port API:
| Method | Description |
|---|---|
Port.I(name: string) | Creates an input port with the given name |
Port.O(name: string) | Creates an output port with the given name |
port.attach(node) | Attaches a port to a component node |
port.connect(targetPort) | Connects this port to another port |
The Component class automatically creates two default ports:
this.inPort - Input port named "in"this.outPort - Output port named "out"Sources: packages/core/src/component/index.ts1-17
The Component class supports two execution modes, enabling flexible composition patterns:
run())In standalone mode, components are invoked directly with input data. This mode is useful for testing or simple, non-pipelined execution.
The run() method is designed to be overridden by subclasses to implement component-specific logic:
packages/core/src/component/index.ts19-21
_transform())In pipeline mode, components participate in reactive data flows. The _transform() method is automatically invoked by the pipeline execution engine when data arrives on input ports.
The default _transform() implementation bridges the two modes by calling run():
packages/core/src/component/index.ts29-34
Sources: packages/core/src/component/index.ts19-34 examples/text-splitter/index.ts52-76
The Pipeline class orchestrates multiple components into a directed graph workflow. It manages component registration, port connections, and execution flow without requiring intermediate adapters.
Sources: packages/core/src/pipeline/index.ts8-16
Components are added to the pipeline using addComponent(), which maintains a name-to-instance mapping:
packages/core/src/pipeline/index.ts66-72
The pipeline stores components in a Map<string, Node>, allowing retrieval by name. Component names must be unique within a pipeline.
Sources: packages/core/src/pipeline/index.ts10 packages/core/src/pipeline/index.ts66-72
The connect() method establishes data flow between components by linking output ports to input ports. Connection identifiers use the format "componentName.portName".
Connection Parsing Logic:
packages/core/src/pipeline/index.ts23-37
packages/core/src/pipeline/index.ts44-58
The from() and to() methods parse the dot-notation format, retrieve the component, and access the appropriate port using the Hlang O() and I() methods respectively.
Connection Execution:
packages/core/src/pipeline/index.ts84-90
Sources: packages/core/src/pipeline/index.ts23-90
The run() method orchestrates pipeline execution by:
BaseProducer and BaseConsumer componentsFlow execution engineInternal Component Management:
packages/core/src/pipeline/index.ts100-114
Automatic Exit Point Detection:
The pipeline automatically determines the exit point by examining connection pairs:
packages/core/src/pipeline/index.ts128-157
If no explicit connections exist (single-component pipeline), the exit point is inferred from the trigger component itself.
Public API:
packages/core/src/pipeline/index.ts179-185
Sources: packages/core/src/pipeline/index.ts99-185
The pipeline uses two hidden components to manage data flow boundaries:
| Component | Role | Identifier |
|---|---|---|
BaseProducer | Injects input data into the pipeline | START_COMPONENT_NAME |
BaseConsumer | Collects final output from the pipeline | END_COMPONENT_NAME |
These components are automatically created and managed by the pipeline—users never interact with them directly. They serve as the pipeline's "virtual" entry and exit points.
Sources: packages/core/src/pipeline/index.ts3-6 packages/core/src/pipeline/index.ts100-114
The complete lifecycle of a component within a pipeline execution follows this pattern:
Sources: packages/core/src/component/index.ts29-34 packages/core/src/pipeline/index.ts99-185
A minimal pipeline with one component demonstrates the automatic exit point inference:
examples/text-splitter/index.ts48-76
In this example:
TextSplitter component is added to the pipelineSTART → textSplitter.text and textSplitter.out → ENDrun()More complex pipelines explicitly connect components:
The pipeline ensures:
_transform() method is invoked reactivelySources: examples/text-splitter/index.ts48-76 README.md264-280
The core package maintains a clean separation between AStack semantics and Hlang runtime primitives:
AStack adds:
"componentName.portName" syntaxrun() method alongside _transform()inPort and outPort on all componentsBaseProducer and BaseConsumer injectionSources: packages/core/src/component/index.ts1-40 packages/core/src/pipeline/index.ts1-189
The core package uses tsup for building and outputs multiple formats:
| Output Format | File Extension | Purpose |
|---|---|---|
| ESM | .js | Modern module format |
| CJS | .cjs | Node.js compatibility |
| TypeScript Declarations | .d.ts, .d.cts | Type information |
Build Tools: pnpm-lock.yaml88-90
The package is built as part of the monorepo using Turbo for parallel execution and dependency-aware caching.
| Dependency | Version | Purpose |
|---|---|---|
typescript | 5.9.2 | TypeScript compiler |
tsup | 8.5.0 | Build bundler |
vitest | 1.6.1 | Unit testing |
eslint | 8.57.1 | Code linting |
rimraf | 5.0.10 | Clean build artifacts |
Sources: pnpm-lock.yaml78-96
The core package uses TypeScript generics to maintain type safety across component boundaries:
| Generic Type | Usage | Example |
|---|---|---|
Pipeline.run<T>() | Specifies pipeline output type | run<string[]>('comp.in', data) |
Component.run() | Returns unknown by default, override to specify | Custom components define return type |
The pipeline's run() method returns a Promise<T> where T is the expected output type:
packages/core/src/pipeline/index.ts179-185
Sources: packages/core/src/pipeline/index.ts179 examples/text-splitter/index.ts66-70 pnpm-lock.yaml78-96
The @astack-tech/core package exports the following public API:
| Export | Type | Description |
|---|---|---|
Component | Class | Base class for all AStack components |
Pipeline | Class | Workflow orchestration system |
Port | Object | Port creation utilities (via Component.Port) |
All other classes and utilities in the package are internal implementation details and should not be directly imported by user code.
Sources: tsconfig.json18-19 packages/core/src/component/index.ts1-40 packages/core/src/pipeline/index.ts1-189
Refresh this wiki