Files
LocalAI/pkg/addons/contract/execution.go
T
Ettore Di Giacinto 2a491cb2cf refactor(addons): remove the shims for older add-on data
No release carried add-ons, so nothing reads older add-on data or
manifests. Delete the code that did.

- Connectors: the kind and the add-on of the Telegram connectors that
  core once carried are gone (LegacyAddon, KindTelegram, the stored
  binding normalization, the platform titles). A binding needs a kind,
  and its add-on is the one that serves the kind. The conversion of the
  old agent pool lists every connector as dropped instead of making a
  Telegram binding, and its notes say so.
- The library index reads only the id field of an entry, not addonId.
- A host control that has a capability block (the network policy) is
  attached by that block alone, not by a tool that replaces bash.
- The Office create tools no longer answer for the argument names of an
  earlier schema, and the identity file note about old addresses is
  gone.
- The known debt of the provider-name guard drops the entries of the
  conversion and of the resource listing shim, and its ceiling goes
  from 13 to 5.

Assisted-by: Claude:claude-sonnet-5-5 go test
2026-11-03 16:56:49 +00:00

104 lines
3.7 KiB
Go

// SPDX-License-Identifier: MIT
package contract
import (
"fmt"
"slices"
)
// ExecutionClassCommands is the class of a tool that runs shell commands and
// code: the tool that shadows bash.
const ExecutionClassCommands = "commands"
// Kinds of skills a commands provider can supply the runtime for.
const (
// SkillKindDocuments are the skills of the document slots (see
// DocumentSkill). They need a provider that reports isolated execution.
SkillKindDocuments = "documents"
)
// Limits of the text the host shows for an execution provider.
const (
MaxExecutionTitleChars = 40
MaxExecutionNoteChars = 600
)
// ExecutionDescriptor is what an add-on declares about the tool that runs
// commands. It carries no authority. Whether commands are ready and isolated
// is what the provider reports at run time (ExecutionStatus); the host decides
// from that report and never from the add-on's ID.
type ExecutionDescriptor struct {
// Class is ExecutionClassCommands.
Class string `json:"class"`
// Title names the provider in the text the host shows the person and the
// model, for example "Sandbox". It falls back to the add-on's title.
Title string `json:"title,omitempty"`
// Note is one plain sentence for the model when the provider reports
// isolated execution, such as the programs its environment has.
Note string `json:"note,omitempty"`
// Skills says which skills run on this provider.
Skills *ExecutionSkills `json:"skills,omitempty"`
}
// ExecutionSkills declares the skills whose runtime the provider supplies.
type ExecutionSkills struct {
// ProvidesRuntimeFor lists skill kinds (SkillKindDocuments). The host
// offers the add-on's skills of those kinds only while the provider
// reports isolated execution.
ProvidesRuntimeFor []string `json:"providesRuntimeFor,omitempty"`
}
// validate checks the descriptor of tool d. A nil descriptor is valid.
func (e *ExecutionDescriptor) validate(d ToolDefinition) error {
if e == nil {
return nil
}
if e.Class != ExecutionClassCommands || d.Shadows != "bash" {
return fmt.Errorf("tool %s: an execution descriptor has class %q and belongs to a tool that shadows bash", d.Name, ExecutionClassCommands)
}
if e.Title != "" && !plainText(e.Title, MaxExecutionTitleChars) {
return fmt.Errorf("tool %s: invalid execution title", d.Name)
}
if e.Note != "" && !plainText(e.Note, MaxExecutionNoteChars) {
return fmt.Errorf("tool %s: invalid execution note", d.Name)
}
if e.Skills != nil {
for _, k := range e.Skills.ProvidesRuntimeFor {
if k != SkillKindDocuments {
return fmt.Errorf("tool %s: unknown skill kind %q", d.Name, k)
}
}
}
return nil
}
// CommandsTool returns the tool of the definitions that shadows bash.
func CommandsTool(defs []ToolDefinition) (ToolDefinition, bool) {
i := slices.IndexFunc(defs, func(d ToolDefinition) bool { return d.Shadows == "bash" && ValidateShadow(d) == nil })
if i < 0 {
return ToolDefinition{}, false
}
return defs[i], true
}
// IsolatedSkills lists the skills of an add-on that need its own commands
// provider to report isolated execution: the document-slot skills of an
// add-on with a commands tool, unless its descriptor says it does not provide
// the runtime for documents. A commands tool without a descriptor counts as providing it, so such an add-on keeps the check.
func IsolatedSkills(defs []ToolDefinition, skills []SkillDefinition) []string {
tool, ok := CommandsTool(defs)
if !ok {
return nil
}
if e := tool.Execution; e != nil && (e.Skills == nil || !slices.Contains(e.Skills.ProvidesRuntimeFor, SkillKindDocuments)) {
return nil
}
var out []string
for _, s := range SlotsOf(skills) {
if s.Kind == SlotKindDocuments {
out = append(out, s.Name)
}
}
return out
}