Skip to content

Commit

Permalink
197 version 007 updates (#208)
Browse files Browse the repository at this point in the history
* 20240516 @Mookse
- alert background -> aliceblue

* 20240517 @Mookse
- `createBot` endpoint
- cosmetic

* 20240518 @Mookse
- `updateTools` becomes `updateAssistant`
- fix: merge error

* 20240518 @Mookse
- createBot, type=journaler succeeds

* 20240518 @Mookse
- icon asset

* 202401518 @Mookse
- journal-thumb.png
- cosmetic console clear

* 20240519 @Mookse
- entrySummary()

* 20240519 @Mookse
- cosmetic

* 20240519 @Mookse
- Teams placeholder
- addTeamMember()
- getAvailableTeamMembers(team)

* 20240520 @Mookse
- public/private avatar placeholder toggle
- cosmetic
  • Loading branch information
Mookse authored May 21, 2024
1 parent 6b26fbf commit cb9644e
Show file tree
Hide file tree
Showing 14 changed files with 910 additions and 222 deletions.
3 changes: 0 additions & 3 deletions inc/js/agents/system/asset-assistant.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ class oAIAssetAssistant {
// setters
// private functions
async #embedFile(){
const file = this.#uploadedFileList[0]
console.log(file)
console.log('#embedFile() begin')
const _metadata = {
source: 'corporate', // logickify
source_id: file.originalFilename,
Expand Down
62 changes: 38 additions & 24 deletions inc/js/functions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ async function about(ctx){
* @returns {object} Koa Context object
*/
function activateBot(ctx){
ctx.state.avatar.activeBotId = ctx.params.bid
ctx.body = { activeBotId: ctx.state.avatar.activeBotId }
const { avatar, } = ctx.state
avatar.activeBotId = ctx.params.bid
ctx.body = { activeBotId: avatar.activeBotId }
}
async function alerts(ctx){
// @todo: put into ctx the _type_ of alert to return, system use dataservices, member use personal
Expand All @@ -30,33 +31,35 @@ async function alerts(ctx){
}
async function bots(ctx){
const bot = ctx.request.body
const { avatar } = ctx.state
switch(ctx.method){
case 'POST': // create new bot
ctx.body = await ctx.state.avatar.setBot(bot)
ctx.body = await avatar.setBot(bot)
break
case 'PUT': // update bot
if(ctx.params.bid!==bot.id)
throw new Error('invalid bot data')
ctx.body = await ctx.state.avatar.setBot(bot)
ctx.body = await avatar.setBot(bot)
break
case 'GET':
default:
if(ctx.params?.bid?.length){ // specific bot
ctx.body = await ctx.state.avatar.bot(ctx.params.bid)
ctx.body = await avatar.bot(ctx.params.bid)
} else {
ctx.body = {
activeBotId: ctx.state.avatar.activeBotId,
bots: await ctx.state.avatar.bots,
mbr_id: ctx.state.avatar.mbr_id,
activeBotId: avatar.activeBotId,
bots: await avatar.bots,
mbr_id: avatar.mbr_id,
}
}
break
}
}
function category(ctx){ // sets category for avatar
ctx.state.category = ctx.request.body
ctx.state.avatar.setActiveCategory(ctx.state.category)
ctx.body = ctx.state.avatar.category
const { avatar, } = ctx.state
avatar.setActiveCategory(ctx.state.category)
ctx.body = avatar.category
}
/**
* Challenge the member session with a passphrase.
Expand All @@ -69,21 +72,22 @@ function category(ctx){ // sets category for avatar
* @property {object} ctx.body - The result of the challenge.
*/
async function challenge(ctx){
if(!ctx.params.mid?.length) ctx.throw(400, `requires member id`)
if(!ctx.params.mid?.length)
ctx.throw(400, `requires member id`)
ctx.body = await ctx.session.MemberSession.challengeAccess(ctx.request.body.passphrase)
}
async function chat(ctx){
const { botId, message, role, threadId, } = ctx.request.body
?? {} /* body nodes sent by fe */
if(!message?.length)
ctx.throw(400, 'missing `message` content')
const response = await ctx.state.avatar.chatRequest(botId, threadId, message)
const { avatar, } = ctx.state
const response = await avatar.chatRequest(botId, threadId, message, )
ctx.body = response
}
async function collections(ctx){
const { avatar, } = ctx.state
const { type, } = ctx.params
ctx.body = await avatar.collections(type)
ctx.body = await avatar.collections(ctx.params.type)
}
/**
* Manage delivery and receipt of contributions(s).
Expand All @@ -99,19 +103,26 @@ async function contributions(ctx){
: mSetContributions(ctx)
)
}
async function createBot(ctx){
const { team, type, } = ctx.request.body
const { avatar, } = ctx.state
const bot = { type, } // `type` only requirement to create a known, MyLife-typed bot
ctx.body = await avatar.createBot(bot)
}
/**
* Delete an item from collection via the member's avatar.
* @async
* @public
* @requires ctx.state.avatar - The avatar object for the member.
* @param {object} ctx - Koa Context object
* @param {object} ctx - Koa Context object
* @returns {boolean} - Under `ctx.body`, status of deletion.
*/
async function deleteItem(ctx){
const { iid, } = ctx.params
const { avatar, } = ctx.state
if(!iid?.length)
ctx.throw(400, `missing item id`)
ctx.body = await ctx.state.avatar.deleteItem(iid)
ctx.body = await avatar.deleteItem(iid)
}
/**
* Request help about MyLife.
Expand All @@ -130,7 +141,6 @@ async function help(ctx){
* Index page for the application.
* @async
* @public
* @requires ctx.state.avatar - The avatar object for the member or Q.
* @param {object} ctx - Koa Context object
*/
async function index(ctx){
Expand All @@ -146,10 +156,11 @@ async function index(ctx){
* @property {string} ctx.body - The interface mode for the member.
*/
function interfaceMode(ctx){
const { avatar, } = ctx.state
if(ctx.method==='POST' && ctx.request.body.mode){
ctx.state.avatar.mode = ctx.request.body.mode
avatar.mode = ctx.request.body.mode
}
ctx.body = ctx.state.avatar.mode
ctx.body = avatar.mode
return
}
async function login(ctx){
Expand Down Expand Up @@ -184,12 +195,13 @@ async function members(ctx){ // members home
await ctx.render('members')
}
async function passphraseReset(ctx){
if(ctx.state.avatar.isMyLife)
const { avatar, } = ctx.state
if(avatar?.isMyLife ?? true)
ctx.throw(400, `cannot reset system passphrase`)
const { passphrase } = ctx.request.body
if(!passphrase?.length)
ctx.throw(400, `passphrase required for reset`)
ctx.body = await ctx.state.avatar.resetPassphrase(passphrase)
ctx.body = await avatar.resetPassphrase(passphrase)
}
async function privacyPolicy(ctx){
ctx.state.title = `MyLife Privacy Policy`
Expand Down Expand Up @@ -287,14 +299,15 @@ function mGetContributions(ctx){
* @param {object} ctx Koa Context object
*/
function mSetContributions(ctx){
const { avatar, } = ctx.state
if(!ctx.params?.cid)
ctx.throw(400, `missing contribution id`) // currently only accepts single contributions via post with :cid
ctx.state.cid = ctx.params.cid
const _contribution = ctx.request.body?.contribution??false
if(!_contribution)
ctx.throw(400, `missing contribution data`)
ctx.state.avatar.contribution = ctx.request.body.contribution
return ctx.state.avatar.contributions
avatar.contribution = ctx.request.body.contribution
return avatar.contributions
.filter(_contribution => (_contribution.id === ctx.state.cid))
.map(_contribution => (_contribution.memberView))
}
Expand All @@ -309,6 +322,7 @@ export {
chat,
collections,
contributions,
createBot,
deleteItem,
help,
index,
Expand Down
148 changes: 113 additions & 35 deletions inc/js/globals.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,123 @@ import EventEmitter from 'events'
import { Guid } from 'js-guid' // usage = Guid.newGuid().toString()
/* constants */
const mAiJsFunctions = {
entrySummary: {
description: 'Generate a JOURNAL ENTRY `entry` summary with keywords and other critical data elements.',
name: 'entrySummary',
parameters: {
type: 'object',
properties: {
content: {
description: 'concatenated raw text content of member input for JOURNAL ENTRY.',
},
keywords: {
description: 'Keywords most relevant to JOURNAL ENTRY.',
items: {
description: 'Keyword (single word or short phrase) to be used in JOURNAL ENTRY summary.',
maxLength: 64,
type: 'string'
},
maxItems: 12,
minItems: 3,
type: 'array'
},
mood: {
description: 'Record member mood for day (or entry) in brief as ascertained from content of JOURNAL ENTRY.',
maxLength: 256,
type: 'string'
},
relationships: {
description: 'Record individuals (or pets) mentioned in this `entry`.',
type: 'array',
items: {
description: 'A name of relational individual/pet to the `entry` content.',
type: 'string'
},
maxItems: 24
},
summary: {
description: 'Generate a JOURNAL ENTRY summary from input.',
maxLength: 20480,
type: 'string'
},
title: {
description: 'Generate display Title of the JOURNAL ENTRY.',
maxLength: 256,
type: 'string'
}
},
required: [
'content',
'keywords',
'summary',
'title'
]
}
},
storySummary: {
description: "Generate a STORY summary with keywords and other critical data elements.",
name: "storySummary",
description: 'Generate a STORY summary with keywords and other critical data elements.',
name: 'storySummary',
parameters: {
type: "object",
type: 'object',
properties: {
keywords: {
description: "Keywords most relevant to STORY.",
description: 'Keywords most relevant to STORY.',
items: {
description: "Keyword (single word or short phrase) to be used in STORY summary.",
description: 'Keyword (single word or short phrase) to be used in STORY summary.',
maxLength: 64,
type: "string"
type: 'string'
},
maxItems: 12,
minItems: 3,
type: "array"
type: 'array'
},
phaseOfLife: {
description: "Phase of life indicated in STORY.",
description: 'Phase of life indicated in STORY.',
enum: [
"birth",
"childhood",
"adolescence",
"teenage",
"young-adult",
"adulthood",
"middle-age",
"senior",
"end-of-life",
"past-life",
"unknown",
"other"
'birth',
'childhood',
'adolescence',
'teenage',
'young-adult',
'adulthood',
'middle-age',
'senior',
'end-of-life',
'past-life',
'unknown',
'other'
],
maxLength: 64,
type: "string"
type: 'string'
},
relationships: {
description: "MyLife Biographer Bot does its best to record individuals (or pets) mentioned in this `story`.",
type: "array",
description: 'MyLife Biographer Bot does its best to record individuals (or pets) mentioned in this `story`.',
type: 'array',
items: {
description: "A name of relational individual/pet to the `story` content.",
type: "string"
description: 'A name of relational individual/pet to the `story` content.',
type: 'string'
},
maxItems: 24
},
summary: {
description: "Generate a STORY summary from input.",
description: 'Generate a STORY summary from input.',
maxLength: 20480,
type: "string"
type: 'string'
},
title: {
description: "Generate display Title of the STORY.",
description: 'Generate display Title of the STORY.',
maxLength: 256,
type: "string"
type: 'string'
}
},
required: [
"keywords",
"phaseOfLife",
"summary",
"title"
'keywords',
'phaseOfLife',
'summary',
'title'
]
}
}
},
}
const mEmailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ // regex for email validation
const mGuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i // regex for GUID validation
Expand All @@ -77,8 +130,33 @@ class Globals extends EventEmitter {
super()
}
/* public functions */
/**
* Get a GPT File Search Tool structure.
* @param {string} vectorstoreId - the vector store id to search.
* @returns {object} - { file_search: { vector_store_ids: [vectorstoreId] } } - the GPT File Search Tool structure.
*/
getGPTFileSearchToolStructure(vectorstoreId){
return {
tools: [{ type: 'file_search' }],
tool_resources: {
file_search: {
vector_store_ids: vectorstoreId ? [vectorstoreId] : []
}
},
}
}
/**
* Get a GPT Javascript function by name.
* @param {string} name - the name of the function to retrieve.
* @returns {object} - {type: 'function', function, } - the function object.
*/
getGPTJavascriptFunction(name){
return this.GPTJavascriptFunctions[name]
if(!name?.length)
throw new Error('getGPTJavascriptFunction() expects a function name as parameter')
return {
type: 'function',
function: this.GPTJavascriptFunctions[name]
}
}
getRegExp(str, isGlobal = false) {
if (typeof str !== 'string' || !str.length)
Expand Down
Loading

0 comments on commit cb9644e

Please sign in to comment.