UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

230 lines (214 loc) 8.06 kB
var schema = { title: "AI Widget Conversation | ${name||_id}", display: "AI Convo (new)", info: "Lightweight conversation log for external AI widgets.", summary:{ description:'Lightweight, persistent conversation record for embeddable AI widgets.', purpose:'Use ai_widget_conversation to track widget chats, including model choice, linked ai_assistant, effective system instructions, and a compact messages array. External sites and test pages create/update these records via the chatgpt widgetStart/widgetMessage/widgetHistory endpoints.', wip:false, labelField:'name', defaultSort:{ field:'last_message_at', dir:'desc' }, searchableFields:['name','info','model','assistant_id','source','user_name','_id'], allowedSorts:['last_message_at','created','joeUpdated','name'], relationships:{ outbound:[ { field:'assistant', targetSchema:'ai_assistant', cardinality:'one' }, { field:'user', targetSchema:'user', cardinality:'one' }, { field:'tags', targetSchema:'tag', cardinality:'many' } ], inbound:{ graphRef:'server/relationships.graph.json' } }, joeManagedFields:['created','joeUpdated'], fields:[ { name:'_id', type:'string', required:true }, { name:'itemtype', type:'string', required:true, const:'ai_widget_conversation' }, { name:'name', type:'string' }, { name:'info', type:'string' }, { name:'model', type:'string' }, { name:'assistant', type:'string', isReference:true, targetSchema:'ai_assistant' }, { name:'assistant_id', type:'string' }, { name:'system', type:'string' }, { name:'messages', type:'objectList' }, { name:'last_message_at', type:'string', format:'date-time' }, { name:'source', type:'string' }, { name:'user', type:'string', isReference:true, targetSchema:'user' }, { name:'user_name', type:'string' }, { name:'user_color', type:'string' }, { name:'assistant_color', type:'string' }, { name:'tags', type:'string', isArray:true, isReference:true, targetSchema:'tag' }, { name:'joeUpdated', type:'string', format:'date-time' }, { name:'created', type:'string', format:'date-time' } ] }, listView: { title: function (convo) { try{ var ts = convo.last_message_at || convo.joeUpdated || convo.created || ''; var prettyTs = (_joe && _joe.Utils && typeof _joe.Utils.prettyPrintDTS === 'function') ? _joe.Utils.prettyPrintDTS(ts) : ts; var title = convo.name || prettyTs || convo._id; function textColorForBg(hex){ if (!hex || typeof hex !== 'string' || !/^#?[0-9a-fA-F]{6}$/.test(hex)) return '#000'; var h = (hex[0] === '#') ? hex.slice(1) : hex; var n = parseInt(h, 16); var r = (n >> 16) & 0xff; var g = (n >> 8) & 0xff; var b = n & 0xff; var luminance = r * 0.299 + g * 0.587 + b * 0.114; return luminance > 186 ? '#000' : '#fff'; } function chip(label,bg){ if(!label){ return ''; } var fg = textColorForBg(bg); return '<span style="display:inline-block;padding:1px 6px;border-radius:999px;font-size:10px;margin-right:4px;background:'+bg+';color:'+fg+';">' + label + '</span>'; } // User chip var userName = ''; var userColor = convo.user_color || ''; if (convo.user){ var u = $J.get(convo.user,'user') || $J.get(convo.user); if (u){ userName = u.fullname || u.name || convo.user_name || ''; userColor = u.color || userColor; } } else if (convo.user_name){ userName = convo.user_name; } var userChip = userName ? chip(userName, userColor || '#4b5563') : ''; // Assistant chip var asstName = ''; var asstColor = convo.assistant_color || ''; if (convo.assistant && _joe && _joe.Data && _joe.Data.ai_assistant){ var a = $J.get(convo.assistant,'ai_assistant') || _joe.Data.ai_assistant.where({_id:convo.assistant})[0]; if (a){ asstName = a.name || a.title || a.assistant_id || a._id; asstColor = a.assistant_color || a.color || asstColor; } } if (!asstName && convo.assistant_id && _joe && _joe.Data && _joe.Data.ai_assistant){ var a2 = _joe.Data.ai_assistant.where({assistant_id:convo.assistant_id})[0]; if (a2){ asstName = a2.name || a2.title || a2.assistant_id || a2._id; asstColor = a2.assistant_color || a2.color || asstColor; }else{ asstName = convo.assistant_id; } } var asstChip = asstName ? chip(asstName, asstColor || '#2563eb') : ''; return '' + '<joe-title>'+title+'</joe-title>' + '<joe-subtitle>'+userChip+asstChip+'</joe-subtitle>' + (prettyTs ? '<joe-subtext>'+prettyTs+'</joe-subtext>' : ''); }catch(e){ return '<joe-title>'+(convo.name||convo._id)+'</joe-title>'; } }, listWindowTitle: "AI Widget Conversations" }, fields: function () { return [ "name", "info", {section_start:"participants"}, { name: "user", type: "select", values: "user", display: "User (JOE)", comment: "User of this conversation.", width: "50%", blank:true }, { name: "assistant", type: "select", values: "ai_assistant", display: "Assistant (JOE)", comment: "Optional link to an ai_assistant config used by this widget.", width: "50%", blank:true }, {section_end:"participants"}, { section_start: "conversation", display: "Conversation", collapsed: false }, { name: "model", type: "select", values: "ai_model", display: "Model", comment: "Default OpenAI model used for this conversation.", width: "50%" }, { name: "assistant_id", type: "text", display: "OpenAI Assistant ID", comment: "Optional OpenAI assistant used for this conversation." }, { name: "system", type: "code", display: "System Instructions", height: "160px", comment: "Effective system prompt used for this conversation." }, { name: "messages", type: "code", display: "Messages (JSON)", height: "260px", comment: "Array of {role, content, created_at}. Managed by the widget API." }, { name: "last_message_at", type: "date", display: "Last Message At", locked: true }, { section_end: "conversation" }, { section_start: "meta", collapsed: true }, "source", "tags", { section_end: "meta" }, { section_start: "system", collapsed: true }, "_id", "created", "joeUpdated", "itemtype", { section_end: "system" } ]; }, // Subsets: grouped quick-filters in the list submenu subsets:function(){ var sets = []; // Group by source (e.g., aihub_card, widget, etc.) sets = sets.concat( _joe.Filter.Options.getDatasetPropertyValues('ai_widget_conversation','source',{ group:'source' }) ); return sets; }, // Filters: sidebar filters filters:function(){ var filters = []; // Distinct users referenced by ai_widget_conversation.user filters = filters.concat( _joe.Filter.Options.datasetProperty('user','user',{ group:'user', collapsed:true }), // Distinct assistants (JOE ai_assistant) referenced by this conversation _joe.Filter.Options.datasetProperty('ai_assistant','assistant',{ group:'assistant', collapsed:true }) ); return filters; }, idprop: "_id", sorter: ["!last_message_at", "!created"] }; module.exports = schema;