Îḿþļéḿéñţîñĝ à Ñéŵ Ţööļ
Ţööļš þŕöçéšš Þàŕţš àš ţĥéý ƒļöŵ ţĥŕöüĝĥ à þîþéļîñé. Ḿöšţ ţööļš öñļý çàŕé àƃöüţ öñé öŕ ţŵö Þàŕţ ţýþéš (üšüàļļý Ƃļöçķš).
Üšîñĝ ƂàšéŢööļ
Ƃüîļđ à 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",
})