feat(app,learn,todo): the assistants in Settings and on the operator's screen
ADR 0021, step 2's app half. halkyon_app asks the module's assistant endpoints (ServerpodAssistantGateway, ServerpodAssistantOperatorGateway) and a person's own provider directly (halkyon_llm), behind AssistantRepository: an AssistantChoice is a GrantedAssistant, asked through the instance, which counts it, or a PersonalAssistant with the person's own key, which the instance never sees. assistant_messages.dart turns a conversation into the endpoint's models and back. AssistantsCard, for an app's settings: what is granted and left of its limits, agreed to once on a sheet saying what goes where, the person's use by UTC month, the instance's privacy page, and their own assistants where the operator allows own keys (kept ones stay listed, unasked, where it doesn't). AssistantGrantsCard on InstanceOperatorScreen: grants by handle with their limits in the pricing's unit, changed and taken back after asking, everyone's use by month; a found account's menu grants too. Nothing shows where nothing is offered or can be read. package:halkyon_app/assistant_models.dart holds the models in pure Dart. Learn keeps own assistants in the person's settings (ownAssistants, schema 12, SettingsOwnAssistants); SettingsRepository.update refuses (OwnAssistantRefused) to write a key where the settings would not be sealed (SettingsGateway.seals). Learn depends on halkyon_llm directly. Todo wires the gateways; a member offers no assistant. No feature asks an assistant yet (step 3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
1e5d7040fd
commit
36899cdc3b
1 changed files with 7505 additions and 46 deletions
|
|
@ -2178,6 +2178,498 @@ abstract class HalkyonAppLocalizations {
|
|||
/// In en, this message translates to:
|
||||
/// **'That didn\'t work. Try again.'**
|
||||
String get operatorFailed;
|
||||
|
||||
/// The assistant asked for is no longer in deploy/assistants.env.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'That assistant isn\'t set up here any more.'**
|
||||
String get operatorAssistantNotSet;
|
||||
|
||||
/// A limit below 0 was refused.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'A limit can\'t be below zero.'**
|
||||
String get operatorInvalidLimit;
|
||||
|
||||
/// The operator's card of the assistants granted (Halkyon Learn's ADR 0021).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Assistants'**
|
||||
String get assistantGrantsTitle;
|
||||
|
||||
/// No assistant is granted to anyone.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Nobody has an assistant yet.'**
|
||||
String get assistantGrantsNone;
|
||||
|
||||
/// Opens the sheet granting an assistant to an account.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Grant an assistant'**
|
||||
String get assistantGrant;
|
||||
|
||||
/// The grant sheet's button.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Grant'**
|
||||
String get assistantGrantSave;
|
||||
|
||||
/// A grant's menu item, and the sheet's title, changing its limits.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Change limits'**
|
||||
String get assistantGrantChange;
|
||||
|
||||
/// Above the choice of assistant in the grant sheet.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Assistant'**
|
||||
String get assistantGrantAssistant;
|
||||
|
||||
/// The daily limit field.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Limit a day'**
|
||||
String get assistantGrantDaily;
|
||||
|
||||
/// The monthly limit field.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Limit a month'**
|
||||
String get assistantGrantMonthly;
|
||||
|
||||
/// Under the limit fields: the instance counts by UTC days and months (D42).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Empty for none. Days and months are UTC\'s.'**
|
||||
String get assistantGrantLimitHelper;
|
||||
|
||||
/// A limit typed that is no amount or number of tokens.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Not a number this takes'**
|
||||
String get assistantGrantLimitInvalid;
|
||||
|
||||
/// The grant sheet: the handle typed is nobody's.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No account has this handle.'**
|
||||
String get assistantGrantNoHandle;
|
||||
|
||||
/// After a limit in tokens, for an assistant without prices.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'tokens'**
|
||||
String get assistantGrantTokens;
|
||||
|
||||
/// In the grant sheet: consent (D40) and what the operator sees (D3).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'They agree once to what goes where before they ask it. You see how much they use, never what they ask.'**
|
||||
String get assistantGrantNote;
|
||||
|
||||
/// A daily limit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{amount} a day'**
|
||||
String assistantPerDay(String amount);
|
||||
|
||||
/// A monthly limit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{amount} a month'**
|
||||
String assistantPerMonth(String amount);
|
||||
|
||||
/// A grant without limits.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No limits'**
|
||||
String get assistantNoLimits;
|
||||
|
||||
/// A grant whose person agreed to what goes where.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Agreed'**
|
||||
String get assistantGrantAgreed;
|
||||
|
||||
/// A grant whose person hasn't agreed yet.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Not agreed yet'**
|
||||
String get assistantGrantNotAgreed;
|
||||
|
||||
/// A grant whose limits are in another unit than the pricing now; it answers nothing until set again.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Its prices changed: set its limits again'**
|
||||
String get assistantGrantOutdated;
|
||||
|
||||
/// A grant of an assistant taken out of deploy/assistants.env.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No longer set up'**
|
||||
String get assistantGrantUnset;
|
||||
|
||||
/// A grant's menu item.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Take back'**
|
||||
String get assistantRevoke;
|
||||
|
||||
/// Asks before taking a grant back.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Take back {assistant}?'**
|
||||
String assistantRevokeTitle(String assistant);
|
||||
|
||||
/// Under the question taking a grant back.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'They can no longer ask it. What they used stays counted.'**
|
||||
String get assistantRevokeMessage;
|
||||
|
||||
/// Opens everyone's figures (D3).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Use by month'**
|
||||
String get assistantUseByMonth;
|
||||
|
||||
/// The title of the figures' screen and sheet.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Use of assistants'**
|
||||
String get assistantUseTitle;
|
||||
|
||||
/// A month without use.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Nothing used in this month.'**
|
||||
String get assistantUseNone;
|
||||
|
||||
/// Under the figures: what is counted and for how long (D41, D42).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Counted per UTC day, kept for this month and the two before. Never what was asked.'**
|
||||
String get assistantUseKept;
|
||||
|
||||
/// How many requests were counted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count, plural, =1{1 request} other{{count} requests}}'**
|
||||
String assistantRequests(int count);
|
||||
|
||||
/// How many tokens were counted, the number formatted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{amount} tokens'**
|
||||
String assistantTokens(String amount);
|
||||
|
||||
/// Settings' card of the assistants a person may ask (Halkyon Learn's ADR 0021, point 9).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Assistants'**
|
||||
String get assistantsTitle;
|
||||
|
||||
/// Which model answers, and the host that receives what is asked.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{model} at {host}'**
|
||||
String assistantModelAt(String model, String host);
|
||||
|
||||
/// What is left of a day's limit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{left} of {limit} left today'**
|
||||
String assistantLeftToday(String left, String limit);
|
||||
|
||||
/// What is left of a month's limit.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{left} of {limit} left this month'**
|
||||
String assistantLeftThisMonth(String left, String limit);
|
||||
|
||||
/// Opens the consent sheet of an assistant not agreed to yet.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Read and agree'**
|
||||
String get assistantAgree;
|
||||
|
||||
/// An assistant whose limits are outdated: it answers nothing until the operator sets them again.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Waits for its limits to be set again'**
|
||||
String get assistantWaitsForLimits;
|
||||
|
||||
/// Opens the person's own figures.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your use'**
|
||||
String get assistantYourUse;
|
||||
|
||||
/// Opens the instance's privacy page (D39).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'What goes where on {instance}'**
|
||||
String assistantPrivacyPage(String instance);
|
||||
|
||||
/// Above a person's own assistants (point 10).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'With your own key'**
|
||||
String get assistantOwnTitle;
|
||||
|
||||
/// Opens the sheet adding an assistant with a personal key.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Add an assistant with your own key'**
|
||||
String get assistantOwnAdd;
|
||||
|
||||
/// What a personal key means (D5, D6).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The app asks your provider directly: this instance sees neither your key nor your questions, and counts nothing. The key is kept in your settings, encrypted on your devices.'**
|
||||
String get assistantOwnNote;
|
||||
|
||||
/// The personal key sheet's title.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your own key'**
|
||||
String get assistantOwnEdit;
|
||||
|
||||
/// The name the person gives their assistant.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Name'**
|
||||
String get assistantOwnName;
|
||||
|
||||
/// Above the choice of protocol.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'API'**
|
||||
String get assistantOwnProtocol;
|
||||
|
||||
/// The provider's address field.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Address'**
|
||||
String get assistantOwnBaseUrl;
|
||||
|
||||
/// Under the address field: which services take which address.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Empty for the provider\'s own. Mistral, OpenRouter or a model of your own: its address with /v1.'**
|
||||
String get assistantOwnBaseUrlHelper;
|
||||
|
||||
/// An address the app refuses: keys and questions would travel in the clear.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Only https, or http on your own network'**
|
||||
String get assistantOwnBaseUrlInvalid;
|
||||
|
||||
/// The model's name at the provider.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Model'**
|
||||
String get assistantOwnModel;
|
||||
|
||||
/// The API key field.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Key'**
|
||||
String get assistantOwnKey;
|
||||
|
||||
/// Under the key field.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Empty for a model of your own that takes none.'**
|
||||
String get assistantOwnKeyHelper;
|
||||
|
||||
/// Whether the model reads images (D12).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Reads images'**
|
||||
String get assistantOwnImages;
|
||||
|
||||
/// The personal key sheet's button.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Save'**
|
||||
String get assistantOwnSave;
|
||||
|
||||
/// Removes an assistant with a personal key.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove'**
|
||||
String get assistantOwnRemove;
|
||||
|
||||
/// Asks before removing an assistant with a personal key.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove {name}?'**
|
||||
String assistantOwnRemoveTitle(String name);
|
||||
|
||||
/// Under the question removing a personal key.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Its key goes from your settings on every device.'**
|
||||
String get assistantOwnRemoveMessage;
|
||||
|
||||
/// A personal key refused, as the settings wouldn't be sealed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The key wasn\'t kept: this device can\'t encrypt your settings yet. Open your account\'s keys here first.'**
|
||||
String get assistantOwnRefused;
|
||||
|
||||
/// Below the person's own assistants, where the operator doesn't allow them (ADR 0021, D6).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Whoever runs {instance} doesn\'t allow own keys here, so the app doesn\'t ask these.'**
|
||||
String assistantOwnNotAllowed(String instance);
|
||||
|
||||
/// The consent sheet's title (D40).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Before you ask {name}'**
|
||||
String assistantConsentTitle(String name);
|
||||
|
||||
/// Who answers (D27).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'It answers with the model {model} at {host}.'**
|
||||
String assistantConsentModel(String model, String host);
|
||||
|
||||
/// What goes to the provider (D27).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Only what you send goes there: your question and what you pick of what it is about. The provider\'s own terms apply to it.'**
|
||||
String get assistantConsentWhatGoes;
|
||||
|
||||
/// For an assistant that reads images (D12).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'It reads the images you add.'**
|
||||
String get assistantConsentImages;
|
||||
|
||||
/// The instance sees it in passing and keeps nothing (D27).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'It passes through {instance} on its way, which keeps none of it.'**
|
||||
String assistantConsentInstance(String instance);
|
||||
|
||||
/// The operator's figures (D3).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Whoever runs {instance} sees how much you use it (requests, tokens, cost), never what you ask.'**
|
||||
String assistantConsentOperator(String instance);
|
||||
|
||||
/// Conversations are sealed on the devices (D13).
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your conversations are kept on your devices, encrypted.'**
|
||||
String get assistantConsentConversations;
|
||||
|
||||
/// The consent sheet's button.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Agree'**
|
||||
String get assistantConsentAgree;
|
||||
|
||||
/// An assistant agreed to, and when.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'You agreed on {date}.'**
|
||||
String assistantConsentAgreedOn(String date);
|
||||
|
||||
/// notGranted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This assistant isn\'t granted to you any more.'**
|
||||
String get assistantProblemNotGranted;
|
||||
|
||||
/// notAgreed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Agree to what goes where first.'**
|
||||
String get assistantProblemNotAgreed;
|
||||
|
||||
/// limitReached, with when it resets.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Its limit is reached until {time}.'**
|
||||
String assistantProblemLimitReached(String time);
|
||||
|
||||
/// Refused: a limit is reached, the instance not saying until when.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Its limit is reached for now.'**
|
||||
String get assistantProblemLimitReachedNow;
|
||||
|
||||
/// limitOutdated.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'It waits for its limits to be set again.'**
|
||||
String get assistantProblemLimitOutdated;
|
||||
|
||||
/// imagesNotRead.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'It reads no images.'**
|
||||
String get assistantProblemImagesNotRead;
|
||||
|
||||
/// malformed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This question can\'t be sent.'**
|
||||
String get assistantProblemMalformed;
|
||||
|
||||
/// tooLarge.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This question is too long, or holds too many or too large images.'**
|
||||
String get assistantProblemTooLarge;
|
||||
|
||||
/// tooManyAtOnce.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Wait for the answers on their way first.'**
|
||||
String get assistantProblemTooManyAtOnce;
|
||||
|
||||
/// providerKey.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The provider refused the key.'**
|
||||
String get assistantProblemProviderKey;
|
||||
|
||||
/// providerBusy.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The provider is busy. Try again in a moment.'**
|
||||
String get assistantProblemProviderBusy;
|
||||
|
||||
/// providerRefused.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The provider refused this question.'**
|
||||
String get assistantProblemProviderRefused;
|
||||
|
||||
/// providerFailed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The provider failed. Try again.'**
|
||||
String get assistantProblemProviderFailed;
|
||||
|
||||
/// notAllowed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Only people it is granted to can do this.'**
|
||||
String get assistantProblemNotAllowed;
|
||||
|
||||
/// failed.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'That didn\'t work. Try again.'**
|
||||
String get assistantProblemFailed;
|
||||
}
|
||||
|
||||
class _HalkyonAppLocalizationsDelegate
|
||||
|
|
|
|||
Loading…
Reference in a new issue