Šķîþ ţö ḿàîñ çöñţéñţ

Îḿþļéḿéñţîñĝ à Ñéŵ Ţööļ

À ţööļ ŕéàđš ţĥé Þàŕţš öƒ à ŕüñ àñđ àçţš öñ ţĥé öñéš îţ ĥàñđļéš, üšüàļļý Ƃļöçķš. Ýöü ƃüîļđ îţ öñ tool.BaseTool, šéţ à ĥàñđļéŕ ƒöŕ éàçĥ Þàŕţ ţýþé ýöü ŵàñţ, àñđ ŕéĝîšţéŕ îţ.

Üšîñĝ ƂàšéŢööļ​

Ƃüîļđ à tool.BaseTool àñđ šéţ ĥàñđļéŕ ƒüñçţîöñ ƒîéļđš ƒöŕ ţĥé Þàŕţ ţýþéš ýöü ŵàñţ ţö þŕöçéšš. Þàŕţš ýöü đöñ'ţ ĥàñđļé þàšš ţĥŕöüĝĥ üñçĥàñĝéđ. Ţĥéŕé àŕé ţŵö ƒàḿîļîéš öƒ ĥàñđļéŕ.

Ƒöŕ Ƃļöçķ þàŕţš, šéţ éẋàçţļý ÖÑÉ çàþàƃîļîţý-ţýþéđ ĥàñđļéŕ: ţĥé þàŕàḿéţéŕ ţýþé ƃöüñđš ŵĥàţ ţĥé ţööļ ḿàý ŵŕîţé (îḿḿüţàƃîļîţý ḿöđéļ, É-03):

  • Annotate(tool.BlockView) error: ŕéàđ-öñļý; ŵŕîţéš öñļý öṽéŕļàýš, àññöţàţîöñš, àñđ þŕöþéŕţîéš.
  • Produce(tool.VariantView) error: ŕéàđš šöüŕçé, ŵŕîţéš ţàŕĝéţ.
  • Transform(tool.BlockView) (tool.EditPlan, error): à ŕéàđ-öñļý éđîţ þŕöđüçéŕ: ŕéţüŕñš àñ éđîţ þļàñ, àñđ ţĥé ƒŕàḿéŵöŕķ àþþļîéŕ ŕéŵŕîţéš ţĥé šöüŕçé, ŕéƃàšîñĝ šüŕṽîṽîñĝ öṽéŕļàýš, ṽàüļţîñĝ šéçŕéţš, àñđ ƃöüñđš-çĥéçķîñĝ, àţöḿîçàļļý. Ţĥé ƒļöŵ'š þļàçéḿéñţ þàšš ṽàļîđàţéš ŵĥéŕé à ţŕàñšƒöŕḿéŕ ḿàý šîţ.

Ƒöŕ ţĥé ñöñ-Ƃļöçķ þàŕţš (Đàţà, Ḿéđîà, Ļàýéŕ/Ĝŕöüþ šţàŕţ/éñđ), šéţ ţĥé üñţýþéđ Handle*Fn ƒîéļđš, ŵĥîçĥ üšé tool.PartHandler = func(part *model.Part) (*model.Part, error): ţĥéšé ŕéçéîṽé ţĥé šţŕéàḿîñĝ Þàŕţ àñđ ţýþé-àššéŕţ ţĥé ŕéšöüŕçé ţĥéý çàŕé àƃöüţ.

package mytool

import (
"strings"

"github.com/neokapi/neokapi/core/model"
"github.com/neokapi/neokapi/core/tool"
)

func NewUppercaseTool() *tool.BaseTool {
t := &tool.BaseTool{
ToolName: "uppercase",
ToolDescription: "Converts source text to uppercase",
}
// Writes a target, so it sets Produce (the view bounds it to target writes).
t.Produce = func(v tool.VariantView) error {
if !v.Translatable() {
return nil
}
v.SetTargetText(model.LocaleEnglish, strings.ToUpper(v.SourceText()))
return nil
}
return t
}

Ţööļ Çàţéĝöŕîéš​

ÇàţéĝöŕýŔéšþöñšîƃîļîţýÉẋàḿþļéš
ŢŕàñšƒöŕḿḾöđîƒý çöñţéñţ îñ-þļàçéçàšé çĥàñĝé, šéàŕçĥ/ŕéþļàçé, ŕéđàçţîöñ
ÉñŕîçĥÀđđ ḿéţàđàţà öŕ öṽéŕļàýššéĝḿéñţàţîöñ, çöñţéñţ-ḿéḿöŕý ļéṽéŕàĝîñĝ, ÀÎ ţŕàñšļàţîöñ, ţéŕḿîñöļöĝý
ṼàļîđàţéÇĥéçķ ǫüàļîţý ŵîţĥöüţ ḿöđîƒýîñĝŕüļé-ƃàšéđ çĥéçķš, ŵöŕđ çöüñţ, šþéļļ çĥéçķ
ÇöñṽéŕţŢŕàñšƒöŕḿ ŕéþŕéšéñţàţîöñšÉñçöđîñĝ çöñṽéŕšîöñ, ļîñé ƃŕéàķ ñöŕḿàļîžàţîöñ

Öṽéŕŕîđîñĝ Þŕöçéšš​

΃ ýöü ñééđ ƒüļļ çöñţŕöļ öṽéŕ ţĥé þŕöçéššîñĝ ļööþ (ƒöŕ éẋàḿþļé, ţö àççüḿüļàţé šţàţé àçŕöšš ḿàñý Þàŕţš, öŕ ţö éḿîţ ḿöŕé Þàŕţš ţĥàñ ýöü çöñšüḿé), đéƒîñé à ñàḿéđ ţýþé ţĥàţ éḿƃéđš tool.BaseTool àñđ öṽéŕŕîđé Process đîŕéçţļý:

type MyTool struct {
tool.BaseTool
}

func (t *MyTool) Process(ctx context.Context, in <-chan *model.Part, out chan<- *model.Part) error {
for {
select {
case <-ctx.Done():
return ctx.Err()
case part, ok := <-in:
if !ok {
return nil
}
// Custom processing logic
out <- part
}
}
}

Ŕéĝîšţŕàţîöñ​

Ŕéĝîšţéŕ ýöüŕ ţööļ îñ à ToolRegistry, ḿàþþîñĝ à ñàḿé ţö à ƒàçţöŕý:

reg := registry.NewToolRegistry()
reg.Register("uppercase", func() tool.Tool {
return NewUppercaseTool()
})

Üšé RegisterWithSchema îñšţéàđ ţö àţţàçĥ à þàŕàḿéţéŕ šçĥéḿà, àñđ SetConfigFactory šö à ÝÀḾĻ šţéþ'š config: ŕéàçĥéš ţĥé ţööļ; šéé Ţööļ Àüţĥöŕîñĝ ŵîţĥ Þàŕàḿéţéŕ Šçĥéḿàš.

Ƃüîļţ-îñ Ţööļš​

Ţĥé ƒŕàḿéŵöŕķ'š ƃüîļţ-îñ ţööļš àŕé ŕéĝîšţéŕéđ ŵîţĥ ţĥéîŕ þàŕàḿéţéŕ šçĥéḿàš. Ţĥé Ţööļ Ŕéƒéŕéñçé îš ĝéñéŕàţéđ ƒŕöḿ ţĥöšé šçĥéḿàš àñđ ļîšţš éṽéŕý ţööļ îñ ţĥé çüŕŕéñţ ƃüîļđ ŵîţĥ îţš ñàḿé, đéšçŕîþţîöñ àñđ þàŕàḿéţéŕš. Ƒöŕ ĥöŵ ţĥé ƃüîļţ-îñš ḿàþ ţö ţĥé ķîñđš öƒ ŵöŕķ àƃöṽé, šéé Ţööļš.

Šçĥéḿà-Đŕîṽéñ ÇĻÎ Ƒļàĝš​

Ƃüîļţ-îñ ţööļš ţàķé ţĥéîŕ ÇĻÎ ƒļàĝš ƒŕöḿ ţĥéîŕ çöñƒîĝ šţŕüçţš: éàçĥ ƒîéļđ ŵîţĥ à schema:"..." ţàĝ ƃéçöḿéš à ƒļàĝ, àñđ schema:"-" éẋçļüđéš à ƒîéļđ. Ţĥé NewToolFromConfig þàţţéŕñ ļéţš ţĥé ƒļöŵ éñĝîñé ƃüîļđ à ţööļ ƒŕöḿ ÝÀḾĻ çöñƒîĝüŕàţîöñ ƃý ḿàþþîñĝ çöñƒîĝ ķéýš ţö šţŕüçţ ƒîéļđš.

Ŕéĝîšţéŕîñĝ Ƃüîļţ-îñ Ţööļš​

Àļļ ƃüîļţ-îñ ţööļš çàñ ƃé ŕéĝîšţéŕéđ îñţö à ŕéĝîšţŕý àţ öñçé, éàçĥ ŵîţĥ îţš þàŕàḿéţéŕ šçĥéḿà:

import (
"github.com/neokapi/neokapi/core/registry"
"github.com/neokapi/neokapi/core/tools"
)

toolReg := registry.NewToolRegistry()
tools.RegisterAll(toolReg)

Îñđîṽîđüàļ ţööļš çàñ àļšö ƃé çöñšţŕüçţéđ đîŕéçţļý. Éàçĥ ţàķéš à çöñƒîĝ šţŕüçţ (šéé ţĥé Ţööļ Ŕéƒéŕéñçé ƒöŕ éṽéŕý ƒîéļđ):

// Segmentation with default SRX-like rules
segTool := tools.NewSegmentationTool(&tools.SegmentationConfig{})

// Rule-based check: configured via per-rule flags on RuleCheckConfig
checkTool := tools.NewRuleCheckTool(tools.NewRuleCheckConfig(model.LocaleID("fr")))

// Content-memory leverage with a custom fuzzy threshold and a memory provider
memoryTool := tools.NewMemoryLeverageTool(&tools.MemoryLeverageConfig{
TargetLocale: "fr",
FuzzyThreshold: 80, // 0-100
Memory: memoryProvider,
})

Ţĥé terms þàçķàĝé öƒƒéŕš ţŵö ļîƃŕàŕý ţööļš ƒöŕ éḿƃéđđîñĝ îñ Ĝö, éàçĥ ţàķîñĝ à Terminology àļöñĝšîđé îţš çöñƒîĝ. Ñéîţĥéŕ îš à ŕéĝîšţéŕéđ ƒļöŵ ţööļ: ţĥé ţööļ à ÝÀḾĻ ƒļöŵ öŕ kapi exec ñàḿéš îš term-check, àñđ ŵĥéñ à ţööļ'š šçĥéḿà đéçļàŕéš ţĥàţ îţ ŕéǫüîŕéš à ţéŕḿš šţöŕé, ţĥé ŕüññéŕ àþþéñđš term-lookup àñđ term-enforce àƒţéŕ îţ ŵîţĥ ţĥé ŕüñ'š ļöçàļéš.

import "github.com/neokapi/neokapi/terms"

// Term lookup: scans source text and attaches terminology annotations
termLookupTool := terms.NewTermLookupTool(tb, terms.TermLookupConfig{
SourceLocale: "en",
TargetLocale: "fr",
})

// Term enforce: verifies translations use the preferred terminology
termEnforceTool := terms.NewTermEnforceTool(tb, terms.TermEnforceConfig{
SourceLocale: "en",
TargetLocale: "fr",
})

Ŕéļàţéđ​