Files
LocalAI/pkg/addons/contract
Ettore Di Giacinto c56c1ac343 feat(addons): choose the connection of a credentialed add-on explicitly
A chat never uses a connection that the host picked for it. For an add-on
whose tools run with the token of a connection (such as GitHub):

- With one connection, it is selected. With several, the Tools menu row
  of the add-on has a Connection selector, and until the person picks one
  the tools are not offered and the row says so. With none, the row says
  so and links to the Connectors page. The choice is stored with the chat
  and its draft, like the other switches, and follows a fork, a
  sub-agent and the runs of a trigger the chat proposed.
- A saved agent can name its connection per add-on (agent form field, API
  field connections). Its chats use it, show it read only and cannot
  change it. An agent with no choice follows the same rule as a chat. A
  chat that a connector binding started keeps using that binding.
- CredentialFor takes the selected binding and uses only it, so the
  resource list of that binding is the only one that applies. A call with
  no selected binding is refused with the code select_connection and a
  note the model can relay. The first-match code (connectors.Pick) is
  removed.
- Tool results and proposal cards say which connection acted, for example
  "as Work, repository acme/widgets". A proposal is applied with the
  connection it was previewed with. The credential use is logged with the
  binding ID.

Contract: the credential slot takes an optional resourceLabel (the word
for the resource in that line). The agent export file does not carry the
connections, since a binding ID belongs to one server.

Assisted-by: Claude:claude-sonnet-5-5 go gofmt ginkgo node playwright protoc swag
2026-11-03 22:02:30 +00:00
..

Typed addon contract

ParseManifest is the strict v1 parser used by staging and package verification. Unknown fields, duplicate keys, invalid declarations, and unsupported compatibility ranges fail validation. The typed declarations remain additive strict v1 fields, not a new protocol version.

  • capabilities.ui.homeCommands names installed pages, never tools or install actions.
  • capabilities.executionProvider names execution tools and one declared UI-only read status tool.
  • capabilities.hostOperations.required and .optional request exact operation names, never grants.
  • capabilities.network declares the egress policy of the commands an add-on runs (kind egress-check, a title, preset titles). It attaches the network-policy host control.

ValidHostOp validates syntax only. The host's registered vocabulary determines support. Administrator policy and request admission remain authoritative, including for optional operations. Status is advisory; an isolation report does not prove network enforcement or authorize execution.

See the addon guide for JSON examples, bounds, collision rules, lifecycle behavior, and policy migration.

Typed owner observations currently support local-owner JSON selections only. Named-user and SQL selections remain unavailable and fail closed; they are not completed scope.

Optional model actions

capabilities.ui.modelActions maps a model capability to a declared page:

{"modelActions":[{"capability":"FLAG_IMAGE","page":"studio","path":"images"}]}

capability and page are required. path is an optional nonempty relative suffix. There is one mapping per capability per addon, at most 27 mappings. The SDK route bounds apply to page/path: 256 ASCII characters, eight segments, and 1–64 characters per segment from [A-Za-z0-9._~-], excluding . and ... Absolute paths, URLs, queries, fragments, percent encoding and backslashes fail. Unknown, duplicate and noncanonical keys fail strict parsing.

The exact vocabulary is ModelActionCapabilities(): all concrete flags in config.GetAllModelConfigUsecases() except native FLAG_CHAT and FLAG_COMPLETION and aggregate FLAG_LLM. FLAG_ANY is not a concrete flag. A core/config parity test guards this list without importing core into contract. Declarations carry no priorities, labels, permissions or model query templates. Apps exposes a cloned typed list only through its existing installed UI view; unavailable UI omission is unchanged. Protocol registration uses the same contract.Capabilities, and verifies exact equality including these actions.

Studio owns image/video/TTS/sound destinations; Talk owns transcription at its existing landing page; Face and Voice own face/speaker recognition respectively. Talk does not currently consume a selected-model query value. Its pipeline and landing semantics remain unchanged. Frontend dispatch and route cleanup are a separate milestone; this contract alone does not change model Open behavior.

The allowed capability strings are:

FLAG_EDIT FLAG_EMBEDDINGS FLAG_RERANK FLAG_IMAGE FLAG_TRANSCRIPT FLAG_TTS
FLAG_SOUND_GENERATION FLAG_TOKENIZE FLAG_VAD FLAG_VIDEO FLAG_DETECTION
FLAG_VISION FLAG_FACE_RECOGNITION FLAG_SPEAKER_RECOGNITION FLAG_AUDIO_TRANSFORM
FLAG_DIARIZATION FLAG_SOUND_CLASSIFICATION FLAG_REALTIME_AUDIO FLAG_SCORE
FLAG_DEPTH FLAG_TOKEN_CLASSIFY FLAG_3D FLAG_3D_ANIMATION FLAG_DECISIONS
FLAG_UPSCALE FLAG_MOTION FLAG_FORECAST

Context files

capabilities.contextFiles names up to three small index files (one for each scope: user, agent, channel) that the host loads into the prompt of a chat.

{"contextFiles":[{"scope":"user","path":"Memory/index.md"},{"scope":"agent","path":"Memory/agents/{agent}/index.md","cap":1024}]}

Every path lies under Memory/, ends in .md and holds no parent segment. An agent path holds {agent} once and a channel path holds {channel} once; the host fills them from the chat, never from the model. cap lowers the 2 KiB index cap; it cannot raise it. The add-on declares and the host reads: the add-on gains no access to the files.