diff --git a/inc/js/core.mjs b/inc/js/core.mjs index dbc52ca..8d32ab9 100644 --- a/inc/js/core.mjs +++ b/inc/js/core.mjs @@ -225,6 +225,9 @@ class Organization extends Member { // form=organization get values(){ return this.core.values } + get version(){ + return this.core.version ?? '0.0.17' + } get vision(){ return this.core.vision } diff --git a/inc/js/globals.mjs b/inc/js/globals.mjs index 0eba89b..19ac995 100644 --- a/inc/js/globals.mjs +++ b/inc/js/globals.mjs @@ -74,7 +74,7 @@ const mAiJsFunctions = { } }, storySummary: { - description: 'Generate a STORY summary with keywords and other critical data elements.', + description: 'Generate a complete multi-paragraph STORY summary with keywords and other critical data elements.', name: 'storySummary', parameters: { type: 'object', @@ -119,8 +119,7 @@ const mAiJsFunctions = { maxItems: 24 }, summary: { - description: 'Generate a STORY summary from input.', - maxLength: 20480, + description: 'A complete multi-paragraph STORY summary composed from relevant user input.', type: 'string' }, title: { diff --git a/inc/js/mylife-avatar.mjs b/inc/js/mylife-avatar.mjs index 4e94414..1bdafa7 100644 --- a/inc/js/mylife-avatar.mjs +++ b/inc/js/mylife-avatar.mjs @@ -192,7 +192,7 @@ class Avatar extends EventEmitter { const conversation = new (this.#factory.conversation)({ mbr_id: this.mbr_id, type, }, this.#factory, thread, botId) if(saveToConversations){ this.#conversations.push(conversation) - console.log('createConversation::save in memory', conversation.thread_id) + console.log('createConversation::saving into local memory', conversation.thread_id) } return conversation } @@ -699,6 +699,8 @@ class Avatar extends EventEmitter { const currentVersion = this.#factory.botInstructionsVersion(type) if(botVersion!==currentVersion){ this.updateInstructions(newActiveId, true, false, true) + /* update bot in this.#bots */ + } this.#activeBotId = newActiveId } @@ -1290,7 +1292,7 @@ function mAvatarDropdown(globals, avatar){ */ async function mBot(factory, avatar, bot){ /* validation */ - const { bots, id: avatarId, isMyLife, mbr_id, vectorstore_id, } = avatar + const { id: avatarId, mbr_id, vectorstore_id, } = avatar const { newGuid, } = factory const { id: botId=newGuid, object_id: objectId, type: botType, } = bot if(!botType?.length) @@ -1298,7 +1300,7 @@ async function mBot(factory, avatar, bot){ bot.mbr_id = mbr_id /* constant */ bot.object_id = objectId ?? avatarId /* all your bots belong to me */ bot.id = botId // **note**: _this_ is a Cosmos id, not an openAI id - let originBot = bots.find(oBot=>oBot.id===botId) + let originBot = avatar.bots.find(oBot=>oBot.id===botId) if(originBot){ /* update bot */ const options = {} const updatedBot = Object.keys(bot) @@ -1317,8 +1319,9 @@ async function mBot(factory, avatar, bot){ avatar.conversations.push(conversation) } } + let updatedOriginBot if(Object.keys(updatedBot).length){ - let updatedOriginBot = {...originBot, ...updatedBot} // consolidated update + updatedOriginBot = {...originBot, ...updatedBot} // consolidated update const { bot_id, id, } = updatedOriginBot updatedBot.bot_id = bot_id updatedBot.id = id @@ -1331,8 +1334,9 @@ async function mBot(factory, avatar, bot){ options.tools = false /* tools not updated through this mechanic */ } updatedOriginBot = await factory.updateBot(updatedBot, options) - originBot = mSanitize(updatedOriginBot) } + originBot = mSanitize(updatedOriginBot ?? originBot) + avatar.bots[avatar.bots.findIndex(oBot=>oBot.id===botId)] = originBot } else { /* create assistant */ bot = mSanitize( await factory.createBot(bot, vectorstore_id) ) avatar.bots.push(bot) diff --git a/inc/js/mylife-llm-services.mjs b/inc/js/mylife-llm-services.mjs index db6aeb3..1c2667c 100644 --- a/inc/js/mylife-llm-services.mjs +++ b/inc/js/mylife-llm-services.mjs @@ -392,26 +392,21 @@ async function mRunFunctions(openai, run, factory, avatar){ // add avatar ref case 'story summary': const story = await factory.story(toolArguments) if(story){ - const { keywords, phaseOfLife='unknown', } = story + const { keywords, phaseOfLife, } = story let { interests, updates, } = factory.core if(typeof interests=='array') interests = interests.join(', ') if(typeof updates=='array') updates = updates.join(', ') - // @stub - action integrates with story and interests/phase switch(true){ + case phaseOfLife?.length: + action = `ask about another encounter during member's ${ phaseOfLife }` + console.log('mRunFunctions()::story-summary::phaseOfLife', phaseOfLife) + break case interests?.length: action = `ask about a different interest from: ${ interests }` console.log('mRunFunctions()::story-summary::interests', interests) break - case phaseOfLife!=='unknown': - action = `ask about another encounter during this phase of life: ${ phaseOfLife }` - console.log('mRunFunctions()::story-summary::phaseOfLife', phaseOfLife) - break - case updates?.length: - action = `ask about current events related to or beyond: ${ updates }` - console.log('mRunFunctions()::story-summary::updates', updates) - break default: action = 'ask about another event in member\'s life' break diff --git a/inc/js/routes.mjs b/inc/js/routes.mjs index 0dfa745..6819655 100644 --- a/inc/js/routes.mjs +++ b/inc/js/routes.mjs @@ -146,7 +146,7 @@ function connectRoutes(_Menu){ * @returns {function} Koa next function */ async function memberValidation(ctx, next) { - if(ctx.state.locked) + if(ctx.state?.locked ?? true) ctx.redirect(`/?type=select`) // Redirect to /members if not authorized await next() // Proceed to the next middleware if authorized } diff --git a/inc/json-schemas/openai/functions/storySummary.json b/inc/json-schemas/openai/functions/storySummary.json index 23662b0..1be222f 100644 --- a/inc/json-schemas/openai/functions/storySummary.json +++ b/inc/json-schemas/openai/functions/storySummary.json @@ -1,5 +1,5 @@ { - "description": "Generate a STORY summary with keywords and other critical data elements.", + "description": "Generate a complete multi-paragraph STORY summary with keywords and other critical data elements.", "name": "storySummary", "parameters": { "type": "object", @@ -44,8 +44,7 @@ "maxItems": 24 }, "summary": { - "description": "Generate a STORY summary from input.", - "maxLength": 20480, + "description": "A complete multi-paragraph STORY summary composed from relevant user input.", "type": "string" }, "title": { diff --git a/server.js b/server.js index b236b47..8f8272f 100644 --- a/server.js +++ b/server.js @@ -166,6 +166,7 @@ app.use(koaBody({ ctx.state.avatar = ctx.state.member.avatar ctx.state.interfaceMode = ctx.state.avatar?.mode ?? 'standard' ctx.state.menu = ctx.MyLife.menu + ctx.state.version = ctx.MyLife.version if(!await ctx.state.MemberSession.requestConsent(ctx)) ctx.throw(404,'asset request rejected by consent') await next() diff --git a/views/assets/css/bots.css b/views/assets/css/bots.css index 34e7d66..d0fd297 100644 --- a/views/assets/css/bots.css +++ b/views/assets/css/bots.css @@ -1,6 +1,7 @@ /* document vars */ :root { --border-radius: 0.22rem; + --collection-item-popup-z-index: calc(var(--mylife-sidebar-z-index)+50); --slider-height: 1rem; --slider-margin: 0.1rem; --slider-width: 2rem; @@ -32,11 +33,9 @@ height: 2.5rem; margin: 0 0.1rem; /* Default margin */ transition: transform 0.3s ease, margin 0.3s ease; - z-index: 1; } .bot-thumb:hover { transform: scale(1.5); - z-index: 2; margin: 0 1rem; /* Increase margin on hover in em */ } .bot-thumb-container { @@ -50,7 +49,6 @@ .bot-thumb-active { background-image: radial-gradient(circle at center, rgba(255, 255, 0, 0.75) 0%, transparent 100%); cursor: not-allowed; - z-index: 3; } /* bot widget */ .bot { /* along with widget */ @@ -72,10 +70,6 @@ display: flex; overflow: auto; } -.bot-content.visible { - /* Show content when active */ - display: block; -} /* team */ .add-team-member-icon { font-size: 1.5rem; @@ -100,7 +94,6 @@ flex-direction: column; justify-content: flex-start; position: absolute; - z-index: 50; } .team-popup-content { background-color: #333; /* Change as needed */ @@ -358,11 +351,14 @@ left: auto; margin: 0; overflow: auto; + opacity: 0; /* Start with hidden popup */ + /* transition: opacity 0.3s; /* Smooth transition */ padding: 0; position: absolute; right: 110vw; top: 0; width: 40em; + z-index: var(--collection-item-popup-z-index); /* above sidebar and other popups */ } .collection-popup-body { display: flex; @@ -563,14 +559,26 @@ input:checked + .publicity-slider:before { padding: 0.5rem; transition: opacity 0.5s ease; /* Smooth transition for opacity */ } -.share-memory-container { /* panel for how others `experience` memory story */ +.relive-memory-button.button { + display: flex; + margin: 0.2rem 0; + padding: 0 0.2rem; + max-width: 80%; + min-width: 60%; +} +.relive-memory-container { /* panel for how others `experience` memory story */ + align-items: center; display: flex; flex-direction: column; justify-content: flex-start; - margin: 0; - padding: 0; + margin: 0.2rem; + padding: 0.2rem; +} +.relive-memory-explanation { + display: flex; + padding: 0.2rem; } -.share-memory-select { /* container for share memory selection packet */ +.relive-memory-select { /* container for share memory selection packet */ display: flex; flex-direction: row; justify-content: space-between; diff --git a/views/assets/css/chat.css b/views/assets/css/chat.css index 9e984e4..be884c6 100644 --- a/views/assets/css/chat.css +++ b/views/assets/css/chat.css @@ -1,3 +1,7 @@ +/* css chat variables */ +:root { + --chat-base-z-index: calc(var(--mylife-base-z-index) + 10); +} /* MyLife chat container */ .agent-bubble { background-color: rgba(0, 86, 179, .85); /* A darker shade of blue for the agent */ @@ -25,26 +29,30 @@ margin-right: 0.5em; } .chat-bubble { - border-radius: 18px; /* Rounded corners for a modern look */ - box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); /* Subtle shadow for depth */ + background-color: #3427ec; /* Assuming a dark bubble color */ + border-radius: 0.8rem; + box-shadow: 0.2rem 0.2rem 0.4rem rgba(0, 0, 0, 0.3); + display: flex; + flex-direction: column; + font-size: 0.9em; margin-bottom: 0.5rem; max-width: 90%; min-width: 30%; - padding: 10px 15px; /* Padding for content inside bubble */ - font-size: .9em; - width: fit-content; /* Fit the content's width */ - word-wrap: break-word; /* Ensure long words don't overflow */ + padding: 0.5rem 0.8rem; + width: fit-content; + word-wrap: break-word; + z-index: calc(var(--chat-base-z-index) + 1); } .chat-container { align-items: flex-start; background-image: - linear-gradient( - to bottom, - rgba(255, 255, 255, 0.85) 0%, + linear-gradient( + to bottom, + rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(66, 66, 66, 0.85) 100% - ), /* White overlay with 50% opacity */ - url('../jpg/cosmos.jpg'); /* Your original background image */ + ), /* White overlay with 50% opacity */ + url('../jpg/cosmos.jpg'); /* Your original background image */ background-size: cover; /* Ensures the image covers the whole area */ background-position: center; /* Centers the image */ border-radius: 22px; @@ -59,16 +67,16 @@ position: relative; width: 100%; } -.chat-member, -.chat-user { - align-items: center; - display: flex; - flex: 1 1 auto; - flex-direction: row; - flex-wrap: wrap; - margin: 0.5em 0; - max-height: 60%; - width: 100%; +.chat-copy, +.chat-feedback { + cursor: pointer; + font-size: 0.8rem; + margin: 0.2rem; + position: absolute; + top: 0.2rem; +} +.chat-feedback { + right: 0.6rem; } .chat-input { background-color: #ffffff; /* White background color */ @@ -87,6 +95,70 @@ padding: 0.3em; /* Padding for space inside the container */ resize: none; /* Allows vertical resizing, none to disable */ } +.chat-member, +.chat-user { + align-items: center; + display: flex; + flex: 1 1 auto; + flex-direction: row; + flex-wrap: wrap; + margin: 0.5em 0; + max-height: 60%; + width: 100%; +} +.chat-message-container { + display: flex; + position: relative; +} +.chat-message-container-agent { + flex-direction: row; +} +.chat-message-container-member, +.chat-message-container-user { + flex-direction: row-reverse; +} +.chat-message-tab { + border-bottom-right-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + display: flex; + flex-direction: column; + height: 100%; + justify-content: flex-end; + opacity: 0; + padding: 0.2rem; + pointer-events: none; + transition: transform 0.5s, opacity 0.5s; + width: 2.5rem; + z-index: var(--chat-base-z-index); +} +.chat-message-tab-agent { + align-items: flex-end; + background-color: #9f9dff; /* Lighter shade of the bubble color */ + border: thin solid #3427ec; + border-top-left-radius: 0; + border-top-right-radius: 0.2rem; + transform: translateX(-100%); +} +.chat-message-tab-hover { + opacity: 1; + pointer-events: all; +} +.chat-message-tab-hover-agent, +.chat-message-tab-agent:hover { + transform: translateX(-33%); /* accommodate for 2.5rem */ +} +.chat-message-tab-member { + align-items: flex-start; + background-color: #d6ffd9; /* Lighter shade of the bubble color */ + border: thin solid #27bbec; + border-top-left-radius: 0.2rem; + border-top-right-radius: 0; + transform: translateX(100%); +} +.chat-message-tab-hover-member, /* **note**: must come after tab-member */ +.chat-message-tab-member:hover { + transform: translateX(33%); /* accommodate for 2.5rem */ +} .chat-refresh { position: absolute; /* Position relative to parent */ top: 0; /* Adjust as needed */ @@ -96,7 +168,7 @@ color: #888; /* Icon color, change as needed */ font-size: 24px; /* Icon size, adjust as needed */ cursor: pointer; /* Pointer cursor on hover */ - z-index: 2; /* Ensure it's above other content */ + z-index: calc(var(--chat-base-z-index) + 5); } /* chat-submit button; requires special treament to overwrite button class for now */ button.chat-submit { /* need specificity to overwrite button class */ @@ -175,14 +247,14 @@ button.chat-submit:disabled { margin: 0 0.5em; justify-content: flex-start; } -.member-bubble, .user-bubble { +.member-bubble, +.user-bubble { background-color: rgba(225, 245, 254, 1); /* A light shade of blue for the user */ color: #333333; /* Dark grey for contrast and easy reading */ font-size: .75em; - margin-left: auto; - margin-right: 12px; } -.member-bubble a, .user-bubble a { +.member-bubble a, +.user-bubble a { color: #333333; /* Dark grey for contrast and easy reading */ } .spinner-green-glow { diff --git a/views/assets/css/experience.css b/views/assets/css/experience.css index a9baefe..edce612 100644 --- a/views/assets/css/experience.css +++ b/views/assets/css/experience.css @@ -2,6 +2,7 @@ /* css experience variables */ :root { --dialog-final-opacity: 0.5; + --experience-base-z-index: calc(var(--mylife-base-z-index) + 100); } /* modal experience screen */ .modal-screen { @@ -18,7 +19,7 @@ position: fixed; top: -100vh; /* Start above the screen */ width: 100vw; - z-index: 10; + z-index: var(--experience-base-z-index); } /* experience transport */ #experience-breadcrumb { @@ -41,7 +42,7 @@ display: none; /* Hide transport controls by default */ justify-content: space-between; padding: 1.2em; - z-index: 100; /* highest z-index */ + z-index: calc(var(--experience-base-z-index) + 10); /* always on top */ } .experience-transport-item { display: flex; @@ -93,7 +94,7 @@ position: absolute; top: 0; width: 100%; - z-index: 15; /* Ensure it's behind the mainstage */ + z-index: var(--experience-base-z-index); /* root experience level */ } .experience-explanation, .experience-title, .experience-description { text-align: center; /* Center text for direct children */ @@ -192,7 +193,7 @@ top: 50%; /* Center vertically */ transform: translate(-50%, -50%); /* Adjust the position to truly center the element */ width: 100vw; /* Auto width based on content */ - z-index: 1000; /* Ensure it's above all other items */ + z-index: calc(var(--experience-base-z-index)+10); /* Ensure it's above all other items */ } .experience-continue-text, .experience-continue-click-text { text-align: center; /* Center the text inside the divs */ @@ -217,7 +218,7 @@ top: 0; /* transition: all 0.3s ease-in-out; /* Smooth transition for any changes */ width: 100%; /* Fill the width of its parent container */ - z-index: 20; /* Ensure it's above the backstage */ + z-index: calc(var(--experience-base-z-index) + 5); /* between backstage and transport */ } .experience-scenestage { display: flex; /* Use flexbox instead of grid */ @@ -500,10 +501,6 @@ .flip { animation: flipAnimation 0.6s ease-in-out forwards; } -.hide { - animation: none !important; - display: none !important; -} .loading-text { color: yellowgreen; font-size: 1.1em; @@ -513,9 +510,6 @@ .pulse { animation: blink 1.5s infinite; } -.show { - display: flex !important; -} .slide, .slide-right, .slide-in { animation: slideInFromLeft 2s ease-in-out forwards; } diff --git a/views/assets/css/main.css b/views/assets/css/main.css index 3210852..a2f3bd2 100644 --- a/views/assets/css/main.css +++ b/views/assets/css/main.css @@ -3,6 +3,12 @@ @import url('chat.css'); @import url('experience.css'); @import url('members.css'); +/* css main variables */ +:root { + --mylife-base-z-index: 1; + --mylife-help-z-index: 5; + --mylife-sidebar-z-index: 20; +} /* MyLife layout */ body { background-color: #000000; @@ -50,7 +56,8 @@ body { .navigation-help, .navigation-login-logout, .navigation-nav, -.navigation-padding { +.navigation-padding, +.navigation-version { align-items: center; display: flex; flex: none; /* Prevents items from growing */ @@ -71,6 +78,15 @@ body { .navigation-help:hover { color: purple; /* Your existing styles for active link */ } +.navigation-link { + margin: 0em .8em; + text-decoration: none; +} +.navigation-link.active { + color: #007bff; /* Your existing styles for active link */ + font-weight: bold; + cursor: pointer; /* Set cursor to default */ +} .navigation-login-logout { align-self: flex-end; display: flex; @@ -95,14 +111,12 @@ body { .navigation-padding { flex: 1; /* Prevents the brand from growing */ } -.navigation-link { - margin: 0em .8em; - text-decoration: none; -} -.navigation-link.active { - color: #007bff; /* Your existing styles for active link */ - font-weight: bold; - cursor: pointer; /* Set cursor to default */ +.navigation-version { + color: rebeccapurple; + font-size: 0.8rem; + font-style: italic; + font-weight: bold; + padding: 0 2rem; } /* MyLife system alerts */ .alert-container{ @@ -346,9 +360,17 @@ body { opacity: 0; display: none; /* Initially not displayed */ } +.hide { + animation: none !important; + display: none !important; +} .ital { font-style: italic; } +.show { + display: flex !important; + opacity: 1 !important; +} .signup { display: flex; flex-direction: column; @@ -448,7 +470,7 @@ body { padding: 0; position: absolute; width: 45%; /* default width */ - z-index: 100; + z-index: calc(var(--mylife-sidebar-z-index)+10); } .popup-content { color: navy; @@ -584,7 +606,7 @@ body { right: 1em; top: 2.2em; /* Position it right below the parent */ width: 63%; - z-index: 100; /* Make sure it's above other elements */ + z-index: var(--mylife-help-z-index); /* Make sure it's above other elements */ } .help-header { font-size: 1.5rem; @@ -684,14 +706,11 @@ body { flex: 1 1 auto; /* Allows growth and shrinkage */ font-family: "Optima", "Segoe UI", "Candara", "Calibri", "Segoe", "Optima", Arial, sans-serif; font-size: 0.8em; + height: auto; /* Ensure it adjusts based on content */ max-height: 100vh; /* Prevents exceeding the viewport height */ max-width: 35%; padding: 0px; - height: auto; /* Ensure it adjusts based on content */ -} -.visible { - opacity: 1; - display: block; + z-index: var(--mylife-sidebar-z-index); } .widget { align-items: center; /* rows get left-aligned */ diff --git a/views/assets/html/_bots.html b/views/assets/html/_bots.html index 7029dc6..f230db1 100644 --- a/views/assets/html/_bots.html +++ b/views/assets/html/_bots.html @@ -5,7 +5,7 @@
-
System-One Hardcoded
+
@@ -41,7 +41,7 @@
-
System-One Hardcoded
+
@@ -57,109 +57,93 @@
- - -
-
- - + +
- - -
-
- - + +
- - + +
- - + +
- - -
-
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
-
- - -
diff --git a/views/assets/html/_navbar.html b/views/assets/html/_navbar.html index fb2dc36..77d7098 100644 --- a/views/assets/html/_navbar.html +++ b/views/assets/html/_navbar.html @@ -6,6 +6,7 @@ <%= _menuItem.display %> <% }) %> +