GLLM Core v0.3 to v0.4
Adding Custom Components
Overview
The Component API now supports an explicit main entrypoint via the @main decorator, with a resolver that determines which method to execute when calling run(). The legacy _run method remains supported as a fallback but is deprecated.
Resolution precedence for the main entrypoint:
Most derived method decorated with
@main.Method named by the
__main_method__class property.Legacy
_runmethod (deprecated fallback).
The input-parameter model (input_params) is generated from the resolved main method signature for the class.
Defining the main method (new)
Decorate an async instance method with
@main.Only one
@mainmethod per class is allowed.If multiple ancestors define different
@mainmethods, aTypeErroris raised unless the subclass explicitly overrides with its own@main.The
__main_method__class property is still supported but has lower precedence than@main. If both are present, a warning is logged and the decorator takes precedence.The main method must be asynchronous.
Example:
Migrating from the old Component
If your component previously implemented _run, you should migrate to the new @main decorator pattern.
Recommended: Direct Migration (Remove _run)
_run)Rename _run to a meaningful method name and apply @main:
Benefits:
Full compatibility with
as_tool()for LLM tool conversionClean, explicit signature for
input_paramsvalidationFuture-proof (follows framework intent)
Breaking Changes:
Any code directly calling
_run()must be updated to call the new method or userun()If used in a
Pipeline, therun_profilemay be inconsistent until the framework is updated (see note below)
Pipeline Note: As of GLLM Pipeline v0.4.28, the run_profile implementation which analyzes _run for static input validation is still used. If you rely heavily on Pipeline and encounter input routing issues, you may need to temporarily keep _run as a stub or override _analyze_run_method() until the core framework is updated.
Alternative: Preserve Validation/Adapter Logic
If your _run method contains important validation or acts as an adapter (e.g., extracting specific keys from **kwargs), use this pattern:
Benefits:
Preserves validation logic at the entry point
Maintains clean separation between validation and business logic
Full compatibility with
as_tool()andinput_params
Trade-offs:
Requires more refactoring than direct migration
Need to update subclasses if they override
_run
Avoid: Decorating _run with @main
Do not simply add @main to your existing _run method:
Why this breaks:
as_tool()explicitly rejects_runas the main method (raisesRuntimeError)Keeps the deprecated method name, defeating the purpose of migration
Not future-proof when
_runis eventually removed
Backward compatibility (non-migrated components)
Components that only implement
_runcontinue to work. The resolver falls back to_runand logs a deprecation warning recommending the@maindecorator.input_paramscontinues to be generated from_runin this case, so existing pipelines keep working.If both
@mainand__main_method__are defined, a warning is emitted and the decorator wins.
Multiple inheritance considerations
If two different ancestors define different
@mainmethods and the subclass does not explicitly override them, aTypeErroris raised at resolution time.To resolve, explicitly define a
@mainmethod in the subclass to choose the desired entrypoint.
Example resolution:
Troubleshooting
TypeError: "Main method '...' must be asynchronous" — ensure the method decorated with
@mainisasync def.TypeError: "Multiple main methods defined in X" — only one
@mainper class is allowed.TypeError about conflicting main methods across ancestors — add a
@mainmethod in the subclass to explicitly resolve.
Notes and best practices
Prefer an async instance method for the main entrypoint. Avoid using
@staticmethodor@classmethodwith@main.Keep the main method signature representative of the inputs you expect;
input_paramswill be generated from it.You do not need to document
run_profileorinput_paramsin your component’s docstring; these are derived and consumed by the pipeline.
Event Handling
A few adjustments have been made to streamline event handling, both to the EventEmitter as well as the Event schema itself.
Event Emitter Parameter Update
The EventEmitter's emit() method will now only accept actual Event objects as arguments. Passing plain strings directly to the emit() method is no longer supported.
GLLM Core v0.3:
GLLM Core v0.4:
Event Schema Attributes Update
The value attribute of the Event schema now supports the following types:
strfor plain texts.dict[str, Any]for structured values.bytesfor multimodal values.
To accommodate this, a new attribute called value_type has also been added to help conveying a more specific information about the value type of an Event. This attribute is optional. When not defined, it will be derived automatically based on the value attribute:
We can customize the value_type when we want to assign a more specific value type to the event, such as when we want to differentiate the modality type between events with bytes values:
Emitted Event Format Simplification
Native supports for legacy emitted event format that utilizes the data event type is removed. As a result, some adjustments are made to the event-related modules:
The
dataevent type is removed from theEventTypeconstant.Special handling of the
dataevent type across event handlers are removed.
For an example of the comparison between the legacy format from GLLM Core v0.3 and the new simplified format, please refer to the thinking event below:
GLLM Core v0.3 (Legacy Format):
GLLM Core v0.4 (Simplified Format):
Disabling Timeout with Retry Config
When defining a RetryConfig object, setting the timeout attribute to 0.0 will previously cause the timeout to be disabled. Now, setting it to 0.0 will raise an error. Instead, set it to None to disable timeout.
Disabling Timeout Example (v0.3) — Will Raise Error in v0.4
Disabling Timeout Example (v0.4)
Last updated
Was this helpful?