json-object-editor 0.10.425 → 0.10.430
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -0
- package/capp/capp.css +8 -1
- package/capp/capp.js +12 -5
- package/css/joe-ai.css +172 -0
- package/css/joe-styles.css +15 -1
- package/css/joe.css +15 -7
- package/js/JsonObjectEditor.jquery.craydent.js +4 -1
- package/js/joe-ai copy.js +517 -0
- package/js/joe-ai.js +281 -158
- package/js/joe-full.js +4 -1
- package/js/joe.js +4 -7
- package/package.json +1 -1
- package/pages/template.html +2 -1
- package/server/app-config.js +1 -1
- package/server/init.js +1 -1
- package/server/modules/Apps.js +2 -1
- package/server/modules/Server.js +29 -5
- package/server/modules/UniversalShorthand.js +1 -2
- package/server/modules/Utils.js +62 -0
- package/server/schemas/ai_conversation.js +23 -14
- package/server/schemas/ai_tool.js +84 -0
package/server/app-config.js
CHANGED
|
@@ -28,7 +28,7 @@ var apps = function(){
|
|
|
28
28
|
var default_schemas = JOE.webconfig.default_schemas;
|
|
29
29
|
return{
|
|
30
30
|
joe:{
|
|
31
|
-
title:'Platform',
|
|
31
|
+
title:'JOE Platform',
|
|
32
32
|
info:'This is the master Data Model Management System (DMMS) admin page. It has access to all of your schemas and datasets.',
|
|
33
33
|
description:'JOE is the Json Object Editor. The Platform app has access to all your schemas and datasets.',
|
|
34
34
|
plugins:['auth.js','formBuilder.js','reportbuilder.js','callbackTester.js','memberRegistry.js','awsConnect.js','notifier.js','calendar.js','inventory.js','money.js'],
|
package/server/init.js
CHANGED
package/server/modules/Apps.js
CHANGED
|
@@ -495,7 +495,8 @@ function Apps(){
|
|
|
495
495
|
return app;
|
|
496
496
|
}
|
|
497
497
|
this.loadPlugin = function(p){
|
|
498
|
-
logit(moduleName+'loading plugin '+p);
|
|
498
|
+
//logit(moduleName+'loading plugin '+p);
|
|
499
|
+
console.log(JOE.Utils.color('[plugin]', 'plugin'), 'loaded: '+p);
|
|
499
500
|
var plugin;
|
|
500
501
|
if(p.indexOf('.js') == -1){p+= '.js';}
|
|
501
502
|
try{
|
package/server/modules/Server.js
CHANGED
|
@@ -16,6 +16,9 @@ var os = require('os');
|
|
|
16
16
|
const $J = require('./UniversalShorthand');
|
|
17
17
|
var rd = require('renderizer')({templatesDir:path.resolve(JOE.joedir,JOE.webconfig.templatesDir)});
|
|
18
18
|
|
|
19
|
+
function coloredLog(message) {
|
|
20
|
+
console.log(JOE.Utils.color('[server]', 'module'), message);
|
|
21
|
+
}
|
|
19
22
|
var authBool = JOE.isAuthorized = function(req,res){
|
|
20
23
|
var users = (JOE.Data && JOE.Data.user) || [];
|
|
21
24
|
|
|
@@ -140,7 +143,23 @@ server.get(['/API/user/:method'],auth,function(req,res,next){
|
|
|
140
143
|
res.jsonp({logout:true});
|
|
141
144
|
return next();
|
|
142
145
|
break;
|
|
143
|
-
|
|
146
|
+
case 'apps':
|
|
147
|
+
logit('getting apps for '+req.User.name);
|
|
148
|
+
userApps = [];
|
|
149
|
+
if (req.User.apps && req.User.apps.length) {
|
|
150
|
+
req.User.apps.map(function (app) {
|
|
151
|
+
if (JOE.Apps.cache[app]) {
|
|
152
|
+
userApps.push({
|
|
153
|
+
name: app,
|
|
154
|
+
title: JOE.Apps.cache[app].title,
|
|
155
|
+
description: JOE.Apps.cache[app].description
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
res.jsonp({userApps});
|
|
161
|
+
return;//return next();
|
|
162
|
+
break;
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
|
|
@@ -711,12 +730,17 @@ server.get(['/JOE/','/JOE/:appname'],auth,function(req,res,next){
|
|
|
711
730
|
}
|
|
712
731
|
|
|
713
732
|
//var collections = [];
|
|
714
|
-
|
|
733
|
+
let uappsObj = [];
|
|
734
|
+
USER.apps.map(a=>{
|
|
735
|
+
let aa = Apps[a]||{};
|
|
736
|
+
uappsObj.push({name:a,title:aa.title,description:aa.description});
|
|
737
|
+
});
|
|
715
738
|
var payload = {
|
|
716
739
|
APPNAME:currentApp.title || appname,
|
|
717
740
|
APPINFO:JSON.stringify(stringFunctions(currentApp)),
|
|
718
741
|
APPS:apps.join(','),
|
|
719
742
|
USERAPPS:(USER.apps||apps||[]).join(','),
|
|
743
|
+
USERAPPSOBJ:JSON.stringify(uappsObj),
|
|
720
744
|
webconfig:JOE.webconfig,
|
|
721
745
|
settings:settings,
|
|
722
746
|
JOEPATH:JOE.webconfig.joepath,
|
|
@@ -761,21 +785,21 @@ server.get(['/RENDER/:contentType/:templateName'],function(req,res){
|
|
|
761
785
|
|
|
762
786
|
JOE.webDir = webDir = JOE.appDir+'/'+JOE.webconfig.webDir+'/';
|
|
763
787
|
JOE.Utils.setupFileFolder(webDir,'web');
|
|
764
|
-
|
|
788
|
+
coloredLog('listening on '+JOE.webconfig.port);
|
|
765
789
|
|
|
766
790
|
|
|
767
791
|
server.use('/',express.static(JOE.webDir));
|
|
768
792
|
|
|
769
793
|
http.listen(JOE.webconfig.port,function(){
|
|
770
794
|
//console.log('joe listening on '+JOE.webconfig.port);
|
|
771
|
-
|
|
795
|
+
coloredLog('using webDir: '+JOE.webDir);
|
|
772
796
|
});
|
|
773
797
|
JOE.httpServer = http;
|
|
774
798
|
var httpsPort = JOE.webconfig.httpsPort;
|
|
775
799
|
if(httpsPort){
|
|
776
800
|
var httpsServer = https.Server({key: JOE.Pem.serviceKey, cert: JOE.Pem.certificate}, server);
|
|
777
801
|
httpsServer.listen(httpsPort);
|
|
778
|
-
|
|
802
|
+
coloredLog(' https on '+httpsPort);
|
|
779
803
|
JOE.httpsServer = httpsServer;
|
|
780
804
|
// pem.createCertificate({selfSigned:true}, function(err, keys){
|
|
781
805
|
// if(err){
|
package/server/modules/Utils.js
CHANGED
|
@@ -174,6 +174,68 @@ var utils = function(){
|
|
|
174
174
|
}
|
|
175
175
|
return finalItems;
|
|
176
176
|
}
|
|
177
|
+
this.flattenObject = function(id, options = {}) {
|
|
178
|
+
const { recursive = true, depth = 1, visited = new Set() } = options;
|
|
179
|
+
|
|
180
|
+
let object = null;
|
|
181
|
+
|
|
182
|
+
if (id) {
|
|
183
|
+
object = $J.get(id);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!object) return null;
|
|
187
|
+
|
|
188
|
+
const flattened = {};
|
|
189
|
+
const currentId = object._id || object.id;
|
|
190
|
+
if (currentId) visited.add(currentId);
|
|
191
|
+
|
|
192
|
+
for (const [field, val] of Object.entries(object)) {
|
|
193
|
+
if (val === undefined || val === null) continue;
|
|
194
|
+
if (field == '_id'){
|
|
195
|
+
flattened[field] = val;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if(field == 'password'){
|
|
199
|
+
flattened[field] = '********';
|
|
200
|
+
continue;
|
|
201
|
+
|
|
202
|
+
}
|
|
203
|
+
if(field =="status"){
|
|
204
|
+
flattened[field] = $J.get(val);
|
|
205
|
+
continue
|
|
206
|
+
}
|
|
207
|
+
if (typeof val === 'string' && $c.isCuid(val) && recursive && depth > 0) {
|
|
208
|
+
if (!visited.has(val)) {
|
|
209
|
+
const expanded = JOE.Utils.flattenObject(val, {
|
|
210
|
+
recursive,
|
|
211
|
+
depth: depth - 1,
|
|
212
|
+
visited: new Set(visited)
|
|
213
|
+
});
|
|
214
|
+
flattened[field] = expanded || val;
|
|
215
|
+
} else {
|
|
216
|
+
flattened[field] = val;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else if (Array.isArray(val) && val.every(v => typeof v === 'string' && $c.isCuid(v)) && recursive && depth > 0) {
|
|
220
|
+
flattened[field] = val.map(refId => {
|
|
221
|
+
if (!visited.has(refId)) {
|
|
222
|
+
const expanded = JOE.Utils.flattenObject(refId, {
|
|
223
|
+
recursive,
|
|
224
|
+
depth: depth - 1,
|
|
225
|
+
visited: new Set(visited)
|
|
226
|
+
});
|
|
227
|
+
return expanded || refId;
|
|
228
|
+
}
|
|
229
|
+
return refId;
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
flattened[field] = val;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return flattened;
|
|
238
|
+
};
|
|
177
239
|
|
|
178
240
|
return this;
|
|
179
241
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var schema = {
|
|
2
2
|
title: "Ai Conversation | ${name}",
|
|
3
|
+
display:'Ai Convo',
|
|
3
4
|
info: "Tracks AI conversations across users, assistants, and external members, storing only summaries for performance.",
|
|
4
5
|
methods:{
|
|
5
6
|
chatSpawner:async function(object_id){
|
|
@@ -13,11 +14,22 @@ var schema = {
|
|
|
13
14
|
"info",
|
|
14
15
|
|
|
15
16
|
{ section_start: "participants", display: "Participants", collapsed: false },
|
|
16
|
-
{ name: "user", type: "
|
|
17
|
+
{ name: "user", type: "select", values: "user", display: "JOE User", comment: "Select the JOE user who initiated this conversation.",width:'50%'},
|
|
18
|
+
|
|
19
|
+
{name:'assistant',type:"select",values:'ai_assistant',display:'AI Assistant',width:'50%',
|
|
20
|
+
comment:'Select the AI assistant to use for this conversation.',default:function(){
|
|
21
|
+
try{
|
|
22
|
+
var defAi = Ai.getDefaultAssistant();
|
|
23
|
+
return defAi._id;
|
|
24
|
+
}catch(e){
|
|
25
|
+
console.log('Error getting default assistant',e);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
},
|
|
17
29
|
{ name: "members", type: "objectReference", values: "members", display: "External Members"},
|
|
18
|
-
{ name: "assistants", type: "group", cssClass:"ai-options", template:function(ass,curObj){
|
|
19
|
-
|
|
20
|
-
}, values: function() { return _joe.getDataset('ai_assistant'); }, display: "Assistants", cols:2 },
|
|
30
|
+
// { name: "assistants", type: "group", cssClass:"ai-options", template:function(ass,curObj){
|
|
31
|
+
// return `${ass.name} || ${curObj.name}`;
|
|
32
|
+
// }, values: function() { return _joe.getDataset('ai_assistant'); }, display: "Assistants", cols:2 },
|
|
21
33
|
{ section_end: "participants" },
|
|
22
34
|
|
|
23
35
|
{ section_start: "thread", display: "Thread", collapsed: true },
|
|
@@ -28,18 +40,11 @@ var schema = {
|
|
|
28
40
|
{ name: "summary", type: "wysiwyg", display: "Conversation Summary", height: "300px", comment: "Auto-generated after key points or closing." },
|
|
29
41
|
{ section_end: "summary" },
|
|
30
42
|
|
|
31
|
-
{ section_start: "linked", display: "Linked Objects", collapsed: true },
|
|
32
|
-
{ name: "linked_objects", type: "objectlist", display: "Linked Objects", fields: [
|
|
33
|
-
{ name: "schema", type: "text", display: "Schema" },
|
|
34
|
-
{ name: "object_id", type: "text", display: "Object ID" }
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
{ section_end: "linked" },
|
|
38
43
|
|
|
39
44
|
{ section_start: "system", collapsed: true },
|
|
40
45
|
"_id",
|
|
41
46
|
"created",
|
|
42
|
-
"
|
|
47
|
+
"joeUpdated",
|
|
43
48
|
"itemtype",
|
|
44
49
|
{ section_end: "system" },
|
|
45
50
|
|
|
@@ -49,7 +54,7 @@ var schema = {
|
|
|
49
54
|
{
|
|
50
55
|
name: "openChat",
|
|
51
56
|
type: "button",
|
|
52
|
-
display: "
|
|
57
|
+
display: "Continue Conversation",
|
|
53
58
|
icon:"ai_assistant",
|
|
54
59
|
onclick2:function(object){
|
|
55
60
|
if (!object || !object._id) return '';
|
|
@@ -59,14 +64,18 @@ var schema = {
|
|
|
59
64
|
if (!object || !object._id) return '';
|
|
60
65
|
return `_joe.schemas.ai_conversation.methods.chatSpawner('${object._id}');`;
|
|
61
66
|
},
|
|
67
|
+
|
|
62
68
|
},
|
|
69
|
+
{name:'context_objects',type:"objectReference", locked:true,values:function(obj,prop){
|
|
70
|
+
return JOE.getData();
|
|
71
|
+
}},
|
|
63
72
|
{ sidebar_end: "right" },
|
|
64
73
|
|
|
65
74
|
];
|
|
66
75
|
},
|
|
67
76
|
|
|
68
77
|
idprop: "_id",
|
|
69
|
-
sorter: ["
|
|
78
|
+
sorter: ["!created"],
|
|
70
79
|
};
|
|
71
80
|
|
|
72
81
|
module.exports = schema;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Joe AI Tool Schema
|
|
2
|
+
// This schema defines reusable tools for OpenAI Assistants and Chat Completions.
|
|
3
|
+
// Each tool includes a JSON schema for function calling and an executable code block.
|
|
4
|
+
|
|
5
|
+
var schema = {
|
|
6
|
+
title: "Ai Tool | ${name}",
|
|
7
|
+
display: "Ai Tool",
|
|
8
|
+
info: "Reusable Ai tool function for OpenAI tool calling and local execution.",
|
|
9
|
+
//menuicon: `<svg viewBox="0 0 24 24"><path d="M3 6h18M3 12h18M3 18h18"/></svg>`,
|
|
10
|
+
|
|
11
|
+
listView: {
|
|
12
|
+
title: '<joe-title>${name}</joe-title><joe-subtitle>${info}</joe-subtitle>',
|
|
13
|
+
listWindowTitle: 'Ai Tools'
|
|
14
|
+
},
|
|
15
|
+
methods:{
|
|
16
|
+
updateToolProperties:function(propObj){
|
|
17
|
+
//get the current tool properties as json
|
|
18
|
+
// set the tool_properties.name to the passed current objects tool_id
|
|
19
|
+
let rawProps = _jco(true).tool_properties ||"{}";
|
|
20
|
+
var toolProperties = eval('('+rawProps+')')||{};
|
|
21
|
+
toolProperties.name = propObj.name;
|
|
22
|
+
_joe.Fields.set('tool_properties',JSON.stringify(toolProperties,'\n','\t'));
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
fields: function() {
|
|
27
|
+
return [
|
|
28
|
+
"name",
|
|
29
|
+
"info", // Unique identifier
|
|
30
|
+
"description", // Short tool description
|
|
31
|
+
{name:'tool_id', type:'text', display:'Tool ID', comment:'Unique identifier for the tool. Used in OpenAI function calling.',onblur:"_joe.schemas.ai_tool.methods.updateToolProperties({name:this.value});"},
|
|
32
|
+
{ section_start: "schema", display: "OpenAI Tool Schema" },
|
|
33
|
+
{
|
|
34
|
+
name: "tool_properties",
|
|
35
|
+
type: "code",
|
|
36
|
+
display: "Tool Properties (OpenAI format)",
|
|
37
|
+
height: "300px",
|
|
38
|
+
comment:
|
|
39
|
+
`<div>Define the tool funcitonal properties as used in OpenAI tool calling.</div>
|
|
40
|
+
<pre>{
|
|
41
|
+
"type": "function",
|
|
42
|
+
"name": "get_weather",
|
|
43
|
+
"description": "Get current temperature for provided coordinates in celsius.",
|
|
44
|
+
"parameters": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"properties": {
|
|
47
|
+
"latitude": { "type": "number" },
|
|
48
|
+
"longitude": { "type": "number" }
|
|
49
|
+
},
|
|
50
|
+
"required": ["latitude", "longitude"],
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
},
|
|
53
|
+
"strict": true
|
|
54
|
+
}</pre>`
|
|
55
|
+
},
|
|
56
|
+
{ section_end: "schema" },
|
|
57
|
+
|
|
58
|
+
{ section_start: "execution", display: "Server Execution" },
|
|
59
|
+
{
|
|
60
|
+
name: "server_code",
|
|
61
|
+
type: "code",
|
|
62
|
+
display: "Code to Execute (Node.js async)",
|
|
63
|
+
height: "300px",
|
|
64
|
+
comment: "Use `args` as input. Return a string, object, or promise.<br/>e.g. <code>return await joe.search(args.dataset, args.query);</code>"
|
|
65
|
+
},
|
|
66
|
+
{ section_end: "execution" },
|
|
67
|
+
|
|
68
|
+
{ section_start: "meta", collapsed: true },
|
|
69
|
+
"tags",
|
|
70
|
+
"datasets",
|
|
71
|
+
{ section_end: "meta" },
|
|
72
|
+
|
|
73
|
+
{ section_start: "system", collapsed: true },
|
|
74
|
+
"_id",
|
|
75
|
+
"created",
|
|
76
|
+
"itemtype",
|
|
77
|
+
{ section_end: "system" }
|
|
78
|
+
];
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
idprop: "_id"
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
module.exports = schema;
|