Construct universal modules with decoded options

This commit is contained in:
2026-07-17 06:30:56 +00:00
parent ce3a07512f
commit b949e9bbc0
22 changed files with 290 additions and 158 deletions

View File

@@ -21,10 +21,17 @@ const (
var _ contracts.Chunker = (*Chunker)(nil)
type Chunker struct{}
type Options struct {
MaxUnits int
OverlapUnits int
}
func New() *Chunker {
return &Chunker{}
type Chunker struct {
options Options
}
func New(options Options) *Chunker {
return &Chunker{options: options}
}
func (c *Chunker) Key() string {
@@ -39,6 +46,9 @@ func (c *Chunker) Chunk(ctx context.Context, req contracts.ChunkRequest) (contra
if c == nil {
return contracts.ChunkResult{}, chunkerErrorf("chunker must not be nil")
}
if c.options.MaxUnits <= 0 || c.options.OverlapUnits < 0 || c.options.OverlapUnits >= c.options.MaxUnits {
return contracts.ChunkResult{}, chunkerErrorf("chunker options must be initialized by construction")
}
if ctx == nil {
return contracts.ChunkResult{}, chunkerErrorf("context must not be nil")
}
@@ -55,15 +65,10 @@ func (c *Chunker) Chunk(ctx context.Context, req contracts.ChunkRequest) (contra
return contracts.ChunkResult{}, chunkerErrorf("validate source document: %w", err)
}
opts, err := chunkOptionsFrom(req.Options)
if err != nil {
return contracts.ChunkResult{}, err
}
step := opts.maxUnits - opts.overlapUnits
step := c.options.MaxUnits - c.options.OverlapUnits
chunks := make([]source.Chunk, 0, (len(req.Source.Units)+step-1)/step)
for start := 0; start < len(req.Source.Units); start += step {
end := start + opts.maxUnits
end := start + c.options.MaxUnits
if end > len(req.Source.Units) {
end = len(req.Source.Units)
}
@@ -119,36 +124,43 @@ func ModuleSpec() pipeline.ModuleSpec {
}
func Register(registry *pipeline.ChunkerRegistry) error {
return registry.RegisterWithSpec(ModuleSpec(), func() (contracts.Chunker, error) {
return New(), nil
return registry.RegisterBuilderWithSpec(ModuleSpec(), validateOptions, func(request pipeline.BuildRequest) (contracts.Chunker, error) {
options, err := DecodeOptions(request.Options)
if err != nil {
return nil, err
}
return New(options), nil
})
}
type chunkOptions struct {
maxUnits int
overlapUnits int
func validateOptions(options map[string]any) error {
_, err := DecodeOptions(options)
return err
}
func chunkOptionsFrom(options map[string]any) (chunkOptions, error) {
opts := chunkOptions{
maxUnits: defaultMaxUnits,
overlapUnits: defaultOverlapUnits,
func DecodeOptions(options map[string]any) (Options, error) {
if err := pipeline.RejectUnknownOptions(options, "max_units", "overlap_units"); err != nil {
return Options{}, chunkerErrorf("%w", err)
}
opts := Options{
MaxUnits: defaultMaxUnits,
OverlapUnits: defaultOverlapUnits,
}
var err error
if value, ok := options["max_units"]; ok {
opts.maxUnits, err = positiveIntOption("max_units", value)
opts.MaxUnits, err = positiveIntOption("max_units", value)
if err != nil {
return chunkOptions{}, err
return Options{}, err
}
}
if value, ok := options["overlap_units"]; ok {
opts.overlapUnits, err = nonNegativeIntOption("overlap_units", value)
opts.OverlapUnits, err = nonNegativeIntOption("overlap_units", value)
if err != nil {
return chunkOptions{}, err
return Options{}, err
}
}
if opts.overlapUnits >= opts.maxUnits {
return chunkOptions{}, chunkerErrorf("overlap_units must be less than max_units")
if opts.OverlapUnits >= opts.MaxUnits {
return Options{}, chunkerErrorf("overlap_units must be less than max_units")
}
return opts, nil
}