Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions frontend/modules/settings_write.html
Original file line number Diff line number Diff line change
Expand Up @@ -3412,6 +3412,13 @@ <h6 class="mb-1"><lang class="lang_ai_title">Let the software write and read for
</div>

<div id="ai_assistant_config" style="max-width:460px; display:none;">
<div class="form-group" id="ai_live_voice_row">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="ai_live_voice" name="ai_live_voice">
<label class="custom-control-label" for="ai_live_voice"><strong><lang class="lang_ai_live_voice">Let customers talk to it, live: it listens and talks back</lang></strong></label>
</div>
<small class="form-text"><span id="ai_live_voice_state" class="badge badge-secondary mr-1"></span><lang class="lang_ai_live_voice_hint">A microphone appears beside the assistant. The customer speaks and hears it answer, can interrupt it, and it adds to the order as they talk, like a phone call with a waiter. The sound goes from the phone straight to your provider; our servers never hear it. Billed by your provider per minute of audio, which costs several times a typed question; it counts against the monthly limit above. Live voice needs an OpenAI key today. With another provider the microphone still works turn by turn, using the phone's own voice, at the price of a typed question.</lang></small>
</div>
<div class="form-group">
<label for="ai_assistant_greeting"><lang class="lang_ai_assistant_greeting">First thing it says</lang></label>
<input type="text" id="ai_assistant_greeting" class="form-control border-control" maxlength="200" autocomplete="off"
Expand All @@ -3424,13 +3431,6 @@ <h6 class="mb-1"><lang class="lang_ai_title">Let the software write and read for
placeholder="Today's special is the prawn biryani. We are a pure-veg kitchen on Tuesdays. Always offer a drink with a meal. We do not do half portions. Dishes marked spicy are genuinely hot; say so." data-t-placeholder="lang_ai_assistant_instructions_placeholder"></textarea>
<small class="form-text text-muted"><lang class="lang_ai_assistant_instructions_hint">Plain sentences. The assistant follows them wherever they do not break its own rules: it only ever recommends what is on your menu at the prices on it, never promises anything about allergens, and never asks for phone numbers or payment. Up to 1,500 characters; every question carries these notes, so shorter costs less.</lang></small>
</div>
<div class="form-group" id="ai_live_voice_row">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="ai_live_voice" name="ai_live_voice">
<label class="custom-control-label" for="ai_live_voice"><lang class="lang_ai_live_voice">Let customers talk to it, live</lang></label>
</div>
<small class="form-text text-muted"><lang class="lang_ai_live_voice_hint">A microphone appears beside the assistant. The customer speaks and hears it answer, can interrupt it, and it adds to the order as they talk, like a phone call with a waiter. The sound goes from the phone straight to your provider; our servers never hear it. Billed by your provider per minute of audio, which costs several times a typed question; it counts against the monthly limit above. Live voice needs an OpenAI key today. With another provider the microphone still works turn by turn, using the phone's own voice, at the price of a typed question.</lang></small>
</div>
<div class="form-group">
<label><lang class="lang_ai_assistant_how_title">How it works</lang></label>
<ol class="small text-muted pl-3 mb-2">
Expand Down Expand Up @@ -5358,8 +5358,21 @@ <h5 class="card-title"><lang class="lang_module_online_ordering">Online Ordering
</div>
</div>
</div>
<div class="mb-2" id="storefront_talk_row">
<div class="input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text" id="storefront_talk_label"><i class="feather icon-mic mr-1" aria-hidden="true"></i><lang class="lang_storefront_link_talk">Talks to order</lang></span>
</div>
<input type="text" class="form-control" id="storefront_talk_url" readonly aria-labelledby="storefront_talk_label">
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary copy-storefront-link" data-target="storefront_talk_url" aria-label="Copy this address" data-t-aria-label="lang_copy_this_address"><i class="feather icon-copy" aria-hidden="true"></i></button>
<a class="btn btn-outline-secondary storefront-open" data-target="storefront_talk_url" href="#" target="_blank" rel="noopener" aria-label="Open this page" data-t-aria-label="lang_open_this_page"><i class="feather icon-external-link" aria-hidden="true"></i></a>
</div>
</div>
</div>
<small class="form-text text-muted">
<lang class="lang_storefront_links_help">Both work as soon as online ordering is on. The menu address never shows a cart, so it stays useful when you stop taking orders. Print whichever one you want on the table or in the window.</lang>
<lang class="lang_storefront_link_talk_help">The third lands the customer straight in the assistant's conversation, ready to talk where you have switched live voice on (AI page); the menu is right behind it. Add ?ai=talk to any table or room address for the same effect, or ?ai=ask to open the typed assistant.</lang>
</small>
</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions frontend/static/script/js/modules/js/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -8629,6 +8629,9 @@ PosnicPro.settings.storefrontLinks = function () {
if (!base) { base = String(window.location.origin || '').replace(/\/+$/, ''); }
$('#storefront_order_url').val(base + '/order/' + id);
$('#storefront_menu_url').val(base + '/menu/' + id);
/* Lands in the conversation; harmless on a shop with the assistant off,
where it is the ordering page. */
$('#storefront_talk_url').val(base + '/order/' + id + '?ai=talk');
row.show();
};

Expand Down Expand Up @@ -9284,6 +9287,7 @@ PosnicPro.settings.ai = {
if (!PosnicPro.settings.ai._switchWired) {
PosnicPro.settings.ai._switchWired = true;
$(document).on('change', '#ai_ordering_assistant', function () { PosnicPro.settings.ai.syncRows(); });
$(document).on('change', '#ai_live_voice', function () { PosnicPro.settings.ai.syncRows(); });
}
var on = !!$('#ai_provider').val();
var where = PosnicPro.settings.ai.KEY_PAGES[$('#ai_provider').val() || ''];
Expand Down Expand Up @@ -9311,6 +9315,18 @@ PosnicPro.settings.ai = {
door is open: a shop that has not switched it on is not asked to
write for it. */
$('#ai_assistant_config').toggle(on && $('#ai_ordering_assistant').is(':checked'));
/* Say in one word what the microphone will do, so nobody has to
guess from a page of hints why it only transcribed. */
var liveOn = $('#ai_live_voice').is(':checked');
var openai = $('#ai_provider').val() === 'openai';
$('#ai_live_voice_state')
.toggleClass('badge-success', liveOn && openai)
.toggleClass('badge-secondary', !(liveOn && openai))
.text(liveOn && openai
? PosnicPro.i18n.t('lang_ai_live_voice_on', 'Live: the microphone opens a voice call with the assistant')
: liveOn
? PosnicPro.i18n.t('lang_ai_live_voice_needs_openai', 'Live voice needs an OpenAI key; with this provider the microphone works turn by turn')
: PosnicPro.i18n.t('lang_ai_live_voice_off', 'Off: the microphone works turn by turn, with the phone\'s own voice'));
/* A saved key and no key must not look the same. The key never comes
back to the browser, so "saved" is a badge and two buttons, and the
empty box only appears when somebody asks to replace it. */
Expand Down
7 changes: 6 additions & 1 deletion languages/_english.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,11 @@
"lang_ai_key_removed": "Key removed. The AI buttons are hidden until a new one is saved.",
"lang_ai_key_replace": "Replace",
"lang_ai_key_saved": "A key is saved. Type a new one to replace it.",
"lang_ai_live_voice": "Let customers talk to it, live",
"lang_ai_live_voice": "Let customers talk to it, live: it listens and talks back",
"lang_ai_live_voice_hint": "A microphone appears beside the assistant. The customer speaks and hears it answer, can interrupt it, and it adds to the order as they talk, like a phone call with a waiter. The sound goes from the phone straight to your provider; our servers never hear it. Billed by your provider per minute of audio, which costs several times a typed question; it counts against the monthly limit above. Live voice needs an OpenAI key today. With another provider the microphone still works turn by turn, using the phone's own voice, at the price of a typed question.",
"lang_ai_live_voice_needs_openai": "Live voice needs an OpenAI key; with this provider the microphone works turn by turn",
"lang_ai_live_voice_off": "Off: the microphone works turn by turn, with the phone\\",
"lang_ai_live_voice_on": "Live: the microphone opens a voice call with the assistant",
"lang_ai_module_desc": "Writes item descriptions for you. You bring your own AI account and pay that provider directly; we charge nothing. Set it up on the AI assistance page.",
"lang_ai_no_limit": "none",
"lang_ai_not_subscription": "A Claude Pro or ChatGPT Plus subscription does not work here. Those pay for the chat website; an API key is billed separately and, for this kind of use, usually costs far less.",
Expand Down Expand Up @@ -2736,6 +2739,8 @@
"lang_storefront_home_banner": "Home banner",
"lang_storefront_link_menu": "Menu only",
"lang_storefront_link_order": "Takes orders",
"lang_storefront_link_talk": "Talks to order",
"lang_storefront_link_talk_help": "The third lands the customer straight in the assistant's conversation, ready to talk where you have switched live voice on (AI page); the menu is right behind it. Add ?ai=talk to any table or room address for the same effect, or ?ai=ask to open the typed assistant.",
"lang_storefront_links": "Your two addresses",
"lang_storefront_links_help": "Both work as soon as online ordering is on. The menu address never shows a cart, so it stays useful when you stop taking orders. Print whichever one you want on the table or in the window.",
"lang_storefront_logo": "Logo",
Expand Down
9 changes: 7 additions & 2 deletions languages/ta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2968,6 +2968,11 @@
"lang_ai_assistant_how_3": "வாடிக்கையாளர் ஏதாவது சேர்க்க அல்லது நீக்கக் கேட்கும்போது, \"சேர்\" தட்டுவது போலவே பக்கம் அதைச் செய்து, உரையாடலில் அதைச் சொல்லும். உதவியாளர் ஒருபோதும் ஆர்டர் செய்யாது, பணம் பெறாது, தொலைபேசி எண்ணையோ முகவரியையோ பார்க்காது.",
"lang_ai_assistant_how_4": "ஒவ்வொரு கேள்வியும் உங்கள் வழங்குநருக்கு ஒரு அழைப்பு; உங்கள் கணக்கில் கட்டணமாகி, மேலே உள்ள மாதாந்திர வரம்பில் கணக்கிடப்படும்; ஒவ்வொரு போனுக்கும் நிமிடத்திற்கு பன்னிரண்டு கேள்விகள் வரை.",
"lang_ai_assistant_how_5": "முயற்சிக்க: சேமித்து, உங்கள் ஆர்டர் பக்கத்தை போனில் திறந்து, தலைப்பில் உள்ள மின்னல் குறியைத் தட்டுங்கள். இங்கே அணைத்தால் ஒரு நிமிடத்திற்குள் மின்னல் குறி மறையும்.",
"lang_ai_live_voice": "வாடிக்கையாளர்கள் அதனுடன் நேரடியாகப் பேச அனுமதிக்கவும்",
"lang_ai_live_voice_hint": "உதவியாளருக்கு அருகில் ஒரு மைக்ரோஃபோன் தோன்றும். வாடிக்கையாளர் பேசுவார், பதிலைக் கேட்பார், இடையில் குறுக்கிடலாம்; பேசும்போதே அது ஆர்டரில் சேர்க்கும், ஒரு வெயிட்டருடன் தொலைபேசியில் பேசுவது போல. ஒலி போனிலிருந்து நேரடியாக உங்கள் வழங்குநருக்குச் செல்கிறது; எங்கள் சர்வர்கள் அதைக் கேட்பதில்லை. உங்கள் வழங்குநர் ஒலி நிமிடத்திற்குக் கட்டணம் விதிப்பார்; தட்டச்சு கேள்வியை விடப் பல மடங்கு அதிகம்; மேலே உள்ள மாதாந்திர வரம்பில் கணக்கிடப்படும். நேரடிக் குரலுக்கு இன்று OpenAI கீ தேவை. வேறு வழங்குநருடன் மைக்ரோஃபோன் முறை முறையாக, போனின் சொந்தக் குரலில், தட்டச்சு கேள்வியின் விலையில் வேலை செய்யும்."
"lang_ai_live_voice": "வாடிக்கையாளர்கள் அதனுடன் நேரடியாகப் பேச அனுமதிக்கவும்: அது கேட்டுப் பதில் பேசும்",
"lang_ai_live_voice_hint": "உதவியாளருக்கு அருகில் ஒரு மைக்ரோஃபோன் தோன்றும். வாடிக்கையாளர் பேசுவார், பதிலைக் கேட்பார், இடையில் குறுக்கிடலாம்; பேசும்போதே அது ஆர்டரில் சேர்க்கும், ஒரு வெயிட்டருடன் தொலைபேசியில் பேசுவது போல. ஒலி போனிலிருந்து நேரடியாக உங்கள் வழங்குநருக்குச் செல்கிறது; எங்கள் சர்வர்கள் அதைக் கேட்பதில்லை. உங்கள் வழங்குநர் ஒலி நிமிடத்திற்குக் கட்டணம் விதிப்பார்; தட்டச்சு கேள்வியை விடப் பல மடங்கு அதிகம்; மேலே உள்ள மாதாந்திர வரம்பில் கணக்கிடப்படும். நேரடிக் குரலுக்கு இன்று OpenAI கீ தேவை. வேறு வழங்குநருடன் மைக்ரோஃபோன் முறை முறையாக, போனின் சொந்தக் குரலில், தட்டச்சு கேள்வியின் விலையில் வேலை செய்யும்.",
"lang_ai_live_voice_on": "நேரடி: மைக்ரோஃபோன் உதவியாளருடன் ஒரு குரல் அழைப்பைத் திறக்கும்",
"lang_ai_live_voice_off": "அணைப்பு: மைக்ரோஃபோன் முறை முறையாக, போனின் சொந்தக் குரலில் வேலை செய்யும்",
"lang_ai_live_voice_needs_openai": "நேரடிக் குரலுக்கு OpenAI கீ தேவை; இந்த வழங்குநருடன் மைக்ரோஃபோன் முறை முறையாக வேலை செய்யும்",
"lang_storefront_link_talk": "பேசி ஆர்டர்",
"lang_storefront_link_talk_help": "மூன்றாவது முகவரி வாடிக்கையாளரை நேரடியாக உதவியாளரின் உரையாடலில் இறக்கும்; நீங்கள் நேரடிக் குரலை (AI பக்கம்) இயக்கியிருந்தால் பேசத் தயாராக இருக்கும்; மெனு அதற்குப் பின்னால் இருக்கும். அதே விளைவுக்கு எந்த மேசை அல்லது அறை முகவரியிலும் ?ai=talk சேர்க்கவும், அல்லது தட்டச்சு உதவியாளரைத் திறக்க ?ai=ask."
}
Loading
Loading