1
- import LLMServices from "../../mylife-llm-services.mjs"
2
1
import BotAgent from "./bot-agent.mjs"
2
+ import { Share , } from '../../mylife-models.mjs'
3
3
import { Marked } from 'marked'
4
4
/* module constants */
5
5
const mAvailableEventActionMap = {
@@ -272,7 +272,6 @@ class ExperienceAgent {
272
272
Experience = mExperience ( experienceData , this . #botAgent, this . #llm, this . #factory, this . #variables)
273
273
this . #experiences. push ( Experience )
274
274
}
275
- console . log ( )
276
275
await Experience . run ( memberInput )
277
276
return Experience
278
277
}
@@ -376,6 +375,203 @@ class ExperienceEvent {
376
375
this . #portrayed = ! ! portrayed
377
376
}
378
377
}
378
+ /* ShareAgent class */
379
+ /**
380
+ * @class ShareAgent
381
+ * Handles the `sharing` process for Mylife currently only via System Avatar.
382
+ */
383
+ class ShareAgent {
384
+ /* private properties */
385
+ #avatar
386
+ #botAgent // @todo - unclear if necessary
387
+ #factory
388
+ #llm
389
+ #shares= [ ] // current-list of active shares
390
+ constructor ( obj = { } , avatar , factory , llm ) {
391
+ this . #avatar = avatar
392
+ this . #factory = factory
393
+ this . #llm = llm
394
+ obj = this . #factory. globals . sanitize ( obj )
395
+ Object . assign ( this , obj )
396
+ }
397
+ /* public functions */
398
+ /**
399
+ * Accepts the warnings for a share.
400
+ * @param {Guid } instanceId - The Share instance id
401
+ * @returns {Boolean } - The Share acceptance status
402
+ */
403
+ acceptWarnings ( instanceId ) {
404
+ const Share = this . share ( instanceId )
405
+ if ( ! ! Share )
406
+ return Share . acceptWarnings ( )
407
+ else
408
+ throw new Error ( 'Share not found' )
409
+ }
410
+ /**
411
+ * Create share with new data.
412
+ * @param {object } shareData - The share data object
413
+ * @returns {Promise<object> } - The updated Share object
414
+ */
415
+ async create ( shareData ) {
416
+ const share = await this . #factory. createShare ( shareData )
417
+ this . #shares. push ( share . id )
418
+ return share
419
+ }
420
+ /**
421
+ * Deletes a share from MyLife `shares` container and associated object (get itemId from `share` itself).
422
+ * @param {Guid } sid - The Share id
423
+ * @returns {Promise<Boolean> } - Success or failure of the operation
424
+ */
425
+ async delete ( shareId ) {
426
+ const { itemId, } = await this . getShare ( shareId )
427
+ this . #factory. deleteShare ( shareId , itemId )
428
+ this . #shares = this . #shares. filter ( share => share !== shareId )
429
+ return true
430
+ }
431
+ /**
432
+ * Get a share data by id.
433
+ * @param {Guid } sid - The share id
434
+ * @returns {Promise<object> } - The MemberShare document
435
+ */
436
+ async getShare ( shareId ) {
437
+ let response = await this . #factory. getShare ( shareId , this . #factory. mbr_id )
438
+ response = this . #factory. globals . sanitize ( response )
439
+ return response
440
+ }
441
+ /**
442
+ * Gets all owned relevant shares from MyLife `shares` container, either by item or member.
443
+ * @param {Guid } itemId - The item id (optional)
444
+ * @returns {Promise<object[]> } - The MemberShare array
445
+ */
446
+ async getShares ( itemId ) {
447
+ let response = await this . #factory. getShares ( itemId )
448
+ if ( Array . isArray ( response ) )
449
+ response = response . map ( share => this . #factory. globals . sanitize ( share ) )
450
+ return response
451
+ }
452
+ /**
453
+ * Get a memory `Header`.
454
+ * @param {guid } instanceId - Share instanceId
455
+ * @returns {Promise<object> } - shareHeader object
456
+ */
457
+ async header ( instanceId ) {
458
+ const Share = this . share ( instanceId )
459
+ if ( Share && ! Share . header ) {
460
+ let MemberAvatar = await this . #factory. avatarProxy ( Share . mbr_id )
461
+ const shareData = await MemberAvatar . cleanShare ( Share ) // operates directly upon Shared Memory Share
462
+ Share . header = shareData
463
+ }
464
+ return Share ?. header
465
+ }
466
+ /**
467
+ * Plays a public share.
468
+ * @param {Guid } instanceId - The instance id
469
+ * @param {object } input - The recipient input
470
+ * @returns {object } - The next message(s) in the share experience
471
+ */
472
+ async play ( instanceId , input ) {
473
+ const Share = this . share ( instanceId )
474
+ if ( ! Share )
475
+ throw new Error ( 'Share not found' )
476
+ else if ( ! Share . header || ! Share . warningsAccepted )
477
+ return await this . shareHeader ( instanceId )
478
+ else if ( ! Share . initialized )
479
+ await this . shareInit ( Share )
480
+ const shareContent = await Share . play ( input )
481
+ shareContent . scene = new Marked ( ) . parse ( shareContent . scene )
482
+ return shareContent
483
+ }
484
+ share ( instanceId , shareId ) {
485
+ let Share
486
+ if ( this . #factory. globals . isValidGuid ( instanceId ) )
487
+ Share = this . #shares. find ( share => share . instanceId === instanceId )
488
+ else if ( this . #factory. globals . isValidGuid ( shareId ) )
489
+ Share = this . #shares. find ( share => share . id === shareId )
490
+ return Share
491
+ }
492
+ /**
493
+ * Initializes a share experience.
494
+ * @param {Share } Share - The Share instance
495
+ * @returns {object } - The first message(s) in the share experience
496
+ */
497
+ async shareInit ( Share ) {
498
+ if ( ! Share . header ) // set header if not already set
499
+ await this . shareHeader ( Share . instanceId )
500
+ /* scene creation */
501
+ let prompt = `# Scenes\n`
502
+ const shareData = { }
503
+ if ( Share . conclusion ?. length )
504
+ prompt += `- conclusion: ${ Share . conclusion } \n`
505
+ if ( Share . voice ?. length )
506
+ prompt += `- voice: ${ Share . voice } \n`
507
+ prompt += `- summary: ${ Share . summary } `
508
+ const messages = await this . #llm. getLLMResponse ( undefined , mDefaultScriptAdvisorLLMId , prompt )
509
+ if ( messages ?. [ 0 ] ) {
510
+ const { content, thread_id, } = messages [ 0 ]
511
+ const message = content
512
+ . filter ( _content => _content . type === 'text' )
513
+ ?. [ 0 ]
514
+ ?. text
515
+ ?. value
516
+ if ( message ?. length ) {
517
+ const scenes = JSON . parse ( message ) . scenes
518
+ if ( scenes . length === 1 )
519
+ scenes = scenes . first ( )
520
+ . split ( / (? = ( s c e n e \s * \d + : ? \n ? ) ) / i)
521
+ . filter ( item => item . trim ( ) !== '' )
522
+ const lastItem = scenes [ scenes . length - 1 ] . trim ( )
523
+ shareData . scenes = scenes
524
+ }
525
+ if ( thread_id ?. length )
526
+ this . #llm. deleteThread ( thread_id ) // no await
527
+ }
528
+ /* set Conversation */
529
+ shareData . Conversation = await this . #avatar. conversationStart ( 'share' , 'share-agent' , Share . mbr_id )
530
+ Share . init ( shareData )
531
+ setTimeout ( _ => { // @todo - incorporate lock
532
+ if ( this . share ( Share . instanceId ) )
533
+ this . #shares = this . #shares. filter ( share => share . instanceId !== Share . instanceId )
534
+ Share . stop ( )
535
+ } , 10 * 60 * 1000 )
536
+ }
537
+ /**
538
+ * Stops a share experience.
539
+ * @param {Guid } instanceId - The Share instance id
540
+ * @returns {Promise<object> } - The share stop object
541
+ */
542
+ async stop ( instanceId ) {
543
+ const Share = this . share ( instanceId )
544
+ if ( Share ) {
545
+ this . #shares = this . #shares. filter ( share => share . instanceId !== Share . instanceId )
546
+ return {
547
+ responses : Share . stop ( ) ,
548
+ success : true
549
+ }
550
+ }
551
+ }
552
+ /**
553
+ * Update a share with provided data.
554
+ * @param {object } shareData - The share data object
555
+ * @returns {Promise<object> } - The updated Share object
556
+ */
557
+ async update ( shareData ) {
558
+ return await this . #factory. updateShare ( shareData )
559
+ }
560
+ async validateShare ( shareId ) {
561
+ if ( ! this . share ( shareId ) ) { // protect in case instanceId sent
562
+ const share = await this . #factory. getShare ( shareId )
563
+ if ( ! share )
564
+ throw new Error ( `Share not found: ${ shareId } ` )
565
+ share . instanceId = this . #factory. newGuid
566
+ const _Share = new Share ( share )
567
+ if ( ! _Share . mbr_id )
568
+ throw new Error ( 'Invalid Share, no Member associated with content' )
569
+ shareId = _Share . instanceId
570
+ this . #shares. push ( _Share )
571
+ }
572
+ return shareId
573
+ }
574
+ }
379
575
/* module functions */
380
576
/**
381
577
* Creates cast and returns associated `cast` object.
@@ -403,7 +599,7 @@ function mCast(cast, botAgent, Factory){
403
599
case 'member' :
404
600
case 'member-bot' :
405
601
default :
406
- Bot = botAgent . bot ( null , form )
602
+ Bot = botAgent . bot ( undefined , form )
407
603
break
408
604
}
409
605
const Actor = new CastMember ( castMember , Bot , Factory )
@@ -922,7 +1118,7 @@ function mLocation(Experience, eid){
922
1118
eid = eid
923
1119
?? scriptEvents [ 0 ] . id
924
1120
const iteration = 0
925
- const sid = Experience . scene ( null , eid ) . id
1121
+ const sid = Experience . scene ( undefined , eid ) . id
926
1122
return { xid, eid, iteration, sid, }
927
1123
}
928
1124
/**
@@ -969,4 +1165,7 @@ function mReplaceVariables(prompt, variableList, variableValues){
969
1165
return prompt
970
1166
}
971
1167
/* exports */
972
- export default ExperienceAgent
1168
+ export {
1169
+ ExperienceAgent ,
1170
+ ShareAgent ,
1171
+ }
0 commit comments