mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-07 21:13:27 -05:00
The manifest said its text in English only. An add-on can now translate what the host shows to people, and the library list shows it before the add-on is installed. The title and the description use the language maps of ui.title and ui.description, which every host already reads. A new optional field, i18n, translates the connector kinds by language tag. It stays under api 2 and its set of fields is closed: the title and the description of a declared kind, and only where the English kind has them. Tool descriptions, schemas and skills are for the model and stay English. Tags follow the language map rule (at most 16, no English), each string has the limit of its English field, all translated text has at most 12 000 characters, and markup, control characters and direction overrides are refused. A host that does not know the field refuses the manifest, as it refuses any unknown field. The field is part of the manifest, so the package digest and the signature cover it. The catalog generator copies the translated title and description of the manifest into each library entry (ui.titles, ui.descriptions), the host validates them like the manifest values, and a library search matches the English and the translated text. The apps list and the connector kinds return the text of every language and, when the request names a language (lang, else Accept-Language), the resolved text beside the English fields: language, localizedTitle and localizedDescription. No existing field changes. Every add-on on master now has its title and description in Italian, German, Spanish, French, Brazilian Portuguese, Simplified Chinese, Korean and Indonesian, and the chat connectors carry their kind text in the same languages. The packaging tests require that, and that a translation has the fields of the English text it translates. The names of the add-ons that provide a role are matched in their English title only: a translation is often an ordinary word of its language. Assisted-by: Claude:claude-sonnet-5-5 go
87 lines
5.0 KiB
Markdown
87 lines
5.0 KiB
Markdown
# 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](../../../docs/content/features/addons.md#optional-typed-manifest-extensions)
|
||
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 translations
|
||
|
||
The title and the description of an add-on are translated by the language maps of `ui.title` and `ui.description`.
|
||
The top-level `i18n` field translates the text of connector kinds, by language tag:
|
||
|
||
```json
|
||
{"i18n":{"it":{"kinds":{"slack":{"title":"Slack","description":"Parla con uno dei tuoi agenti da Slack."}}}}}
|
||
```
|
||
|
||
The set of fields is closed: only the title and the description of a declared kind, and only where the English kind has them.
|
||
Tool descriptions, schemas and skills are for the model and stay English. English is the manifest itself, so `en` is refused.
|
||
Tags follow the same rule as the language maps, at most 16, and all translated text has at most `MaxI18nChars` characters.
|
||
`NegotiateLanguage` picks the language of a request: the explicit one, else the `Accept-Language` header, else English.
|
||
See [the addon guide](../../../docs/content/features/addons.md#translated-text).
|
||
|
||
## Optional model actions
|
||
|
||
`capabilities.ui.modelActions` maps a model capability to a declared page:
|
||
|
||
```json
|
||
{"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:
|
||
|
||
```text
|
||
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.
|
||
|
||
```json
|
||
{"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.
|