json-object-editor 0.10.650 → 0.10.654
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 +48 -0
- package/_www/mcp-test.html +18 -0
- package/css/joe-ai.css +1 -1
- package/css/joe-styles.css +52 -2
- package/css/joe.css +54 -3
- package/css/joe.min.css +1 -1
- package/docs/joe_agent_custom_gpt_instructions_v_3.md +57 -3
- package/js/JsonObjectEditor.jquery.craydent.js +281 -10
- package/js/joe-ai.js +237 -6
- package/js/joe.js +282 -11
- package/js/joe.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +56 -3
- package/server/apps/aihub.js +1 -0
- package/server/fields/core.js +65 -8
- package/server/modules/MCP.js +1237 -914
- package/server/modules/ThoughtPipeline.js +23 -3
- package/server/plugins/awsConnect.js +31 -1
- package/server/plugins/chatgpt.js +235 -10
- package/server/schemas/ai_pipeline.js +90 -0
- package/server/schemas/ai_prompt.js +2 -0
- package/server/schemas/ai_response.js +171 -17
- package/server/schemas/status.js +12 -2
- package/server/schemas/task.js +9 -3
- package/server/schemas/thought.js +57 -5
- package/server/webconfig.js +1 -1
package/js/joe.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* --------------------------------------------------------
|
|
2
2
|
*
|
|
3
|
-
* json-object-editor - v0.10.
|
|
3
|
+
* json-object-editor - v0.10.654
|
|
4
4
|
* Created by: Corey Hadden
|
|
5
5
|
*
|
|
6
6
|
* -------------------------------------------------------- */
|
|
@@ -5110,9 +5110,145 @@ this.renderHTMLContent = function(specs){
|
|
|
5110
5110
|
} else if (elem.msRequestFullscreen) { /* IE11 */
|
|
5111
5111
|
elem.msRequestFullscreen();
|
|
5112
5112
|
}
|
|
5113
|
-
}
|
|
5113
|
+
};
|
|
5114
5114
|
encapsulateFieldType('code',self.renderCodeField,
|
|
5115
5115
|
{fullscreen:this.fullScreenCodeEditor});
|
|
5116
|
+
|
|
5117
|
+
/*----------------------------->
|
|
5118
|
+
Q.1 | JSON Field
|
|
5119
|
+
<-----------------------------*/
|
|
5120
|
+
this.renderJsonField = function(prop){
|
|
5121
|
+
/*|{
|
|
5122
|
+
tags:'render,field,json',
|
|
5123
|
+
specs:'value,standard_field_properties',
|
|
5124
|
+
description:'JSON object editor using Ace in JSON mode; always pretty-prints on load/blur/save.'
|
|
5125
|
+
}|*/
|
|
5126
|
+
var height = (prop.height)?'style="height:'+prop.height+';"' : '';
|
|
5127
|
+
var editor_id = cuid();
|
|
5128
|
+
var rawValue = (typeof prop.value == "undefined") ? {} : prop.value;
|
|
5129
|
+
var displayValue;
|
|
5130
|
+
// Ensure we start from an object and pretty JSON string
|
|
5131
|
+
if (typeof rawValue == "string") {
|
|
5132
|
+
try{
|
|
5133
|
+
rawValue = JSON.parse(rawValue);
|
|
5134
|
+
}catch(e){
|
|
5135
|
+
// fallback: leave as raw string, Ace/validation will handle parse errors on blur/save
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
if (rawValue === null || typeof rawValue == "undefined") {
|
|
5139
|
+
rawValue = {};
|
|
5140
|
+
}
|
|
5141
|
+
if (typeof rawValue == "object") {
|
|
5142
|
+
try{
|
|
5143
|
+
displayValue = JSON.stringify(rawValue,null,2);
|
|
5144
|
+
}catch(e){
|
|
5145
|
+
displayValue = "{}";
|
|
5146
|
+
}
|
|
5147
|
+
}else{
|
|
5148
|
+
// Non-object (number/boolean/etc.) – stringify as-is but still require valid JSON
|
|
5149
|
+
try{
|
|
5150
|
+
displayValue = JSON.stringify(rawValue,null,2);
|
|
5151
|
+
}catch(e){
|
|
5152
|
+
displayValue = "{}";
|
|
5153
|
+
}
|
|
5154
|
+
}
|
|
5155
|
+
var html =
|
|
5156
|
+
'<div class="clear joe-ace-holder joe-rendering-field joe-field" '
|
|
5157
|
+
+height+' data-ace_id="'+editor_id+'" data-ftype="ace" name="'+prop.name+'">'+
|
|
5158
|
+
'<textarea class="" id="'+editor_id+'" >'
|
|
5159
|
+
+(displayValue || "{}")+
|
|
5160
|
+
'</textarea>'+
|
|
5161
|
+
'</div>'+
|
|
5162
|
+
'<script>'+
|
|
5163
|
+
'try{\
|
|
5164
|
+
var editor = ace.edit("'+editor_id+'");\
|
|
5165
|
+
editor.setTheme("ace/theme/tomorrow");\
|
|
5166
|
+
editor.getSession().setUseWrapMode(true);\
|
|
5167
|
+
editor.getSession().setMode("ace/mode/json");\
|
|
5168
|
+
editor.setOptions({\
|
|
5169
|
+
enableBasicAutocompletion: true,\
|
|
5170
|
+
enableLiveAutocompletion: false\
|
|
5171
|
+
});\
|
|
5172
|
+
_joe.ace_editors["'+editor_id+'"] = editor;\
|
|
5173
|
+
}catch(e){ console && console.warn && console.warn("ACE json init error",e);}'
|
|
5174
|
+
+' </script>';
|
|
5175
|
+
return html;
|
|
5176
|
+
};
|
|
5177
|
+
// Helper to (re)parse and pretty-print a json field from its Ace editor.
|
|
5178
|
+
function _normalizeJsonField(fieldName,opts){
|
|
5179
|
+
opts = opts || {};
|
|
5180
|
+
var parent = getJoe(self.joe_index);
|
|
5181
|
+
var $holder = parent.overlay.find('.joe-ace-holder[name="'+fieldName+'"]');
|
|
5182
|
+
if(!$holder.length){ return { ok:true }; }
|
|
5183
|
+
var editorId = $holder.data('ace_id');
|
|
5184
|
+
var editor = _joe.ace_editors[editorId];
|
|
5185
|
+
if(!editor){ return { ok:true }; }
|
|
5186
|
+
var text = editor.getValue();
|
|
5187
|
+
if(!text || !text.trim()){
|
|
5188
|
+
// default to empty object
|
|
5189
|
+
text = '{}';
|
|
5190
|
+
}
|
|
5191
|
+
try{
|
|
5192
|
+
var parsed = JSON.parse(text);
|
|
5193
|
+
// must be an object; if not, still allow but keep as-is
|
|
5194
|
+
try{
|
|
5195
|
+
var pretty = JSON.stringify(parsed,null,2);
|
|
5196
|
+
editor.setValue(pretty,-1);
|
|
5197
|
+
}catch(_e){}
|
|
5198
|
+
$holder.removeClass('joe-field-error');
|
|
5199
|
+
return { ok:true, parsed:parsed };
|
|
5200
|
+
}catch(e){
|
|
5201
|
+
// Attempt a light-weight "loose JSON" fix for common cases:
|
|
5202
|
+
// - Unquoted identifier keys: { name:"Corey" } -> { "name":"Corey" }
|
|
5203
|
+
// - Single-quoted strings: { "name":'Corey' } -> { "name":"Corey" }
|
|
5204
|
+
// - Trailing commas: { "a":1, } -> { "a":1 }
|
|
5205
|
+
var fixed = text;
|
|
5206
|
+
try{
|
|
5207
|
+
// Quote bare identifier keys following { or , and before :
|
|
5208
|
+
fixed = fixed.replace(/([{\[],\s*|[{]\s*|,\s*)([A-Za-z_][A-Za-z0-9_]*)\s*:/g,function(m,prefix,key){
|
|
5209
|
+
return prefix+'"'+key+'":';
|
|
5210
|
+
});
|
|
5211
|
+
// Convert single-quoted strings to double-quoted strings
|
|
5212
|
+
fixed = fixed.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'/g,'"$1"');
|
|
5213
|
+
// Remove trailing commas before } or ]
|
|
5214
|
+
fixed = fixed.replace(/,\s*([}\]])/g,'$1');
|
|
5215
|
+
|
|
5216
|
+
var reparsed = JSON.parse(fixed);
|
|
5217
|
+
try{
|
|
5218
|
+
var prettyFixed = JSON.stringify(reparsed,null,2);
|
|
5219
|
+
editor.setValue(prettyFixed,-1);
|
|
5220
|
+
}catch(_e2){}
|
|
5221
|
+
$holder.removeClass('joe-field-error');
|
|
5222
|
+
return { ok:true, parsed:reparsed };
|
|
5223
|
+
}catch(_fixErr){
|
|
5224
|
+
$holder.addClass('joe-field-error');
|
|
5225
|
+
if(opts.showMessage && parent.showMessage){
|
|
5226
|
+
parent.showMessage("Field '"+fieldName+"' must be valid JSON (object).");
|
|
5227
|
+
}
|
|
5228
|
+
return { ok:false, error:e };
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
}
|
|
5232
|
+
encapsulateFieldType('json',self.renderJsonField,{
|
|
5233
|
+
ready:function(){
|
|
5234
|
+
// Attach blur handlers to normalize/validate json fields when panel shows
|
|
5235
|
+
var parent = getJoe(self.joe_index);
|
|
5236
|
+
parent.overlay.find('.joe-ace-holder[name]').each(function(){
|
|
5237
|
+
var name = $(this).attr('name');
|
|
5238
|
+
var field = self.getField(name);
|
|
5239
|
+
if(!field){ return true; }
|
|
5240
|
+
var ftype = (self.propAsFuncOrValue(field.type)||'').toLowerCase();
|
|
5241
|
+
if(ftype != 'json'){ return true; }
|
|
5242
|
+
var editorId = $(this).data('ace_id');
|
|
5243
|
+
var editor = _joe.ace_editors[editorId];
|
|
5244
|
+
if(!editor){ return true; }
|
|
5245
|
+
editor.on('blur',function(){
|
|
5246
|
+
_normalizeJsonField(name,{showMessage:false});
|
|
5247
|
+
});
|
|
5248
|
+
});
|
|
5249
|
+
},
|
|
5250
|
+
normalize:_normalizeJsonField
|
|
5251
|
+
});
|
|
5116
5252
|
/*----------------------------->
|
|
5117
5253
|
Q.2 | QR Field
|
|
5118
5254
|
<-----------------------------*/
|
|
@@ -5221,7 +5357,7 @@ this.renderHTMLContent = function(specs){
|
|
|
5221
5357
|
'<div class="joe-uploader-preview">'+dz_message+'</div>'+
|
|
5222
5358
|
'</div>'+
|
|
5223
5359
|
'<div class="joe-uploader-message">add a file</div>'+
|
|
5224
|
-
'<div class="joe-button joe-green-button joe-upload-cofirm-button hidden" onclick="_joe.uploaderConfirm(\''+uploader_id+'\',\''+prop.name+'\');">Upload File</div>'+__clearDiv__+
|
|
5360
|
+
'<div class="joe-button joe-green-button joe-upload-cofirm-button ui-helper-hidden hidden" onclick="_joe.uploaderConfirm(\''+uploader_id+'\',\''+prop.name+'\');">Upload File</div>'+__clearDiv__+
|
|
5225
5361
|
'</div>'
|
|
5226
5362
|
;
|
|
5227
5363
|
//var idprop = prop.idprop || '_id';
|
|
@@ -5248,7 +5384,7 @@ this.renderHTMLContent = function(specs){
|
|
|
5248
5384
|
var jup_template,html= '';
|
|
5249
5385
|
var alink ="<a href='${url}${base64}' class='file-link' target='_blank'></a>";
|
|
5250
5386
|
var delete_btn = '<joe-uploader-file-delete-btn class="svg-shadow" onclick="_joe.Fields.uploader.remove(\''+cuid+'\',\'${filename}\');">'+self.SVG.icon.close+'</joe-uploader-delete-btn>';
|
|
5251
|
-
var label = '
|
|
5387
|
+
var label = '';
|
|
5252
5388
|
|
|
5253
5389
|
|
|
5254
5390
|
files.map(function(file){
|
|
@@ -5273,6 +5409,12 @@ this.renderHTMLContent = function(specs){
|
|
|
5273
5409
|
|
|
5274
5410
|
|
|
5275
5411
|
|
|
5412
|
+
// Build the label with filename and optional OpenAI file id on a new line
|
|
5413
|
+
label = '<joe-uploader-file-label>'+(file.filename || '')+'</joe-uploader-file-label>';
|
|
5414
|
+
if(file.openai_file_id){
|
|
5415
|
+
label += '<joe-uploader-file-oaid >'+file.openai_file_id+'</joe-uploader-file-oaid>';
|
|
5416
|
+
}
|
|
5417
|
+
|
|
5276
5418
|
if((file.type && file.type.contains('image')) || (!file.type && (file.url||file.base64).split('.').contains(['jpg','jpeg','png','gif','svg']))){
|
|
5277
5419
|
jup_template = '<joe-uploader-file class="'+(file.uploaded && 'uploaded'||'')+'" style="background-image:url(${url}${base64})">'+alink+label+filesize+delete_btn+'</joe-uploader-file>';
|
|
5278
5420
|
}else if (docTypes.includes((file.url || file.base64).split('.').pop())) {
|
|
@@ -5284,7 +5426,16 @@ this.renderHTMLContent = function(specs){
|
|
|
5284
5426
|
'<joe-uploader-file-extension >.'+(file.type.split('/')[1] || '???')+'</joe-uploader-file-extension>'+
|
|
5285
5427
|
alink+label+filesize+delete_btn+'</joe-uploader-file>';
|
|
5286
5428
|
}
|
|
5287
|
-
|
|
5429
|
+
// Build optional OpenAI retry/upload button
|
|
5430
|
+
var openaiBtn = '';
|
|
5431
|
+
var needRetry = (!file.openai_file_id || file.openai_status == 'error');
|
|
5432
|
+
var hasUrl = !!file.url;
|
|
5433
|
+
if(hasUrl && needRetry){
|
|
5434
|
+
var openaiLabel = (file.openai_status == 'error') ? 'Retry OpenAI' : 'Upload to OpenAI';
|
|
5435
|
+
var safeFilename = (file.filename || '').replace(/'/g,"\\'");
|
|
5436
|
+
openaiBtn = '<joe-uploader-openai-btn class="joe-button" style="margin-left:6px;" onclick="_joe.SERVER.Plugins.openaiRetryFromUrl(\''+cuid+'\',\''+safeFilename+'\');">'+openaiLabel+'</joe-uploader-openai-btn>';
|
|
5437
|
+
}
|
|
5438
|
+
html += fillTemplate(jup_template,file) + openaiBtn;
|
|
5288
5439
|
})
|
|
5289
5440
|
return html+'<div class="clear"></div>';
|
|
5290
5441
|
}
|
|
@@ -5301,7 +5452,7 @@ this.renderHTMLContent = function(specs){
|
|
|
5301
5452
|
$(joe_uploader.dropzone).find('img,div').replaceWith('<img src="' + base64 + '">')
|
|
5302
5453
|
//joe_uploader.dropzone.html('<img src="' + base64 + '">');
|
|
5303
5454
|
joe_uploader.message.html('<b>'+file.name+'</b> selected');
|
|
5304
|
-
joe_uploader.confirmBtn.removeClass('hidden');
|
|
5455
|
+
joe_uploader.confirmBtn.removeClass('ui-helper-hidden hidden');
|
|
5305
5456
|
}else {
|
|
5306
5457
|
results.innerHTML = 'Nothing to upload.';
|
|
5307
5458
|
}
|
|
@@ -5332,7 +5483,7 @@ this.renderHTMLContent = function(specs){
|
|
|
5332
5483
|
}
|
|
5333
5484
|
joe_uploader.files.push(temp_file);
|
|
5334
5485
|
$(joe_uploader.preview).html(_renderUploaderFilePreviews(joe_uploader.files,joe_uploader.cuid));
|
|
5335
|
-
joe_uploader.confirmBtn.removeClass('hidden');
|
|
5486
|
+
joe_uploader.confirmBtn.removeClass('ui-helper-hidden hidden');
|
|
5336
5487
|
}else {
|
|
5337
5488
|
results.innerHTML = 'Nothing to upload.';
|
|
5338
5489
|
}
|
|
@@ -5400,6 +5551,20 @@ this.renderHTMLContent = function(specs){
|
|
|
5400
5551
|
var fileobj = joe_uploader.files.where({filename:filename})[0];
|
|
5401
5552
|
fileobj.uploaded = new Date();
|
|
5402
5553
|
fileobj.url = url;
|
|
5554
|
+
// Apply captured OpenAI info if present
|
|
5555
|
+
var key = self.current.object._id + '/' + filename;
|
|
5556
|
+
var oi = _joe._lastOpenAI && _joe._lastOpenAI[key];
|
|
5557
|
+
fileobj.openai_purpose = 'assistants';
|
|
5558
|
+
if(oi){
|
|
5559
|
+
fileobj.openai_file_id = oi.openai_file_id || null;
|
|
5560
|
+
fileobj.openai_status = (oi.openai_file_id && 'ok') || (oi.openai_error && 'error') || 'not_uploaded';
|
|
5561
|
+
fileobj.openai_error = oi.openai_error || null;
|
|
5562
|
+
if(oi.openai_error){
|
|
5563
|
+
joe_uploader.message.append('<div>OpenAI error: '+oi.openai_error+'</div>');
|
|
5564
|
+
}
|
|
5565
|
+
}else{
|
|
5566
|
+
fileobj.openai_status = fileobj.openai_status || 'not_uploaded';
|
|
5567
|
+
}
|
|
5403
5568
|
delete fileobj.base64;
|
|
5404
5569
|
}
|
|
5405
5570
|
|
|
@@ -5470,6 +5635,14 @@ this.renderHTMLContent = function(specs){
|
|
|
5470
5635
|
self.uploaders[id].dropzone = $(this).find('.joe-uploader-dropzone');
|
|
5471
5636
|
self.uploaders[id].confirmBtn = $(this).find('.joe-upload-cofirm-button');
|
|
5472
5637
|
|
|
5638
|
+
// If there are pending files (not uploaded or missing url), show the confirm button
|
|
5639
|
+
var pending = (self.uploaders[id].files || []).some(function(file){
|
|
5640
|
+
return $c.isObject(file) && (!file.uploaded || !file.url);
|
|
5641
|
+
});
|
|
5642
|
+
if(pending){
|
|
5643
|
+
self.uploaders[id].confirmBtn.removeClass('ui-helper-hidden hidden');
|
|
5644
|
+
}
|
|
5645
|
+
|
|
5473
5646
|
});
|
|
5474
5647
|
};
|
|
5475
5648
|
encapsulateFieldType('uploader',self.renderUploaderField,
|
|
@@ -7563,6 +7736,11 @@ Field Rendering Helpers
|
|
|
7563
7736
|
//ready objectlist
|
|
7564
7737
|
self.Fields.objectlist.ready();
|
|
7565
7738
|
|
|
7739
|
+
//ready json (Ace-based) fields
|
|
7740
|
+
if(self.Fields.json && self.Fields.json.ready){
|
|
7741
|
+
self.Fields.json.ready();
|
|
7742
|
+
}
|
|
7743
|
+
|
|
7566
7744
|
|
|
7567
7745
|
//sidebars
|
|
7568
7746
|
if(self.current.sidebars){
|
|
@@ -7688,10 +7866,26 @@ Field Rendering Helpers
|
|
|
7688
7866
|
var f,test_info;
|
|
7689
7867
|
for(var c in changes){
|
|
7690
7868
|
f = self.getField(c);
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
7869
|
if(c[0] != '$' && c != 'joeUpdated' && f && f.type !='content' && !parseBoolean(f.passthrough)){
|
|
7694
|
-
|
|
7870
|
+
// Special handling for json fields: compare parsed objects so
|
|
7871
|
+
// whitespace/formatting-only changes are ignored.
|
|
7872
|
+
var ftype = (self.propAsFuncOrValue(f.type)||'').toLowerCase();
|
|
7873
|
+
if(ftype == 'json'){
|
|
7874
|
+
var orig = _joe.current.object[c];
|
|
7875
|
+
var rawNew = cc_construct[c];
|
|
7876
|
+
var sameJson = false;
|
|
7877
|
+
try{
|
|
7878
|
+
var parsedOrig = (typeof orig == "string") ? JSON.parse(orig) : orig;
|
|
7879
|
+
var parsedNew = (typeof rawNew == "string") ? JSON.parse(rawNew) : rawNew;
|
|
7880
|
+
sameJson = (JSON.stringify(parsedOrig) == JSON.stringify(parsedNew));
|
|
7881
|
+
}catch(_e){
|
|
7882
|
+
// parse failure means it is definitely a change that needs attention
|
|
7883
|
+
sameJson = false;
|
|
7884
|
+
}
|
|
7885
|
+
if(sameJson){
|
|
7886
|
+
continue;
|
|
7887
|
+
}
|
|
7888
|
+
}else if(JSON.stringify(_joe.current.object[c]) == JSON.stringify(cc_construct[c])){
|
|
7695
7889
|
continue;
|
|
7696
7890
|
}
|
|
7697
7891
|
if(['qrcode'].indexOf(f.type) != -1){
|
|
@@ -7994,6 +8188,27 @@ Field Rendering Helpers
|
|
|
7994
8188
|
}
|
|
7995
8189
|
var callback = callback || self.current.callback || (self.current.schema && self.current.schema.callback) || defaultCallback; //logit;
|
|
7996
8190
|
var newObj = self.constructObjectFromFields(self.joe_index);
|
|
8191
|
+
// Normalize json fields: parse to objects and block save on invalid JSON.
|
|
8192
|
+
if(_joe && _joe.current && _joe.current.fields){
|
|
8193
|
+
var jsonField, ftype, normResult;
|
|
8194
|
+
for(var i=0, tot=_joe.current.fields.length; i<tot; i++){
|
|
8195
|
+
jsonField = _joe.current.fields[i];
|
|
8196
|
+
ftype = (self.propAsFuncOrValue(jsonField.type)||'').toLowerCase();
|
|
8197
|
+
if(ftype != 'json'){ continue; }
|
|
8198
|
+
// Ensure editor content is normalized and valid
|
|
8199
|
+
normResult = self.Fields.json && self.Fields.json.normalize
|
|
8200
|
+
? self.Fields.json.normalize(jsonField.name,{showMessage:true})
|
|
8201
|
+
: { ok:true };
|
|
8202
|
+
if(!normResult.ok){
|
|
8203
|
+
// invalid JSON – do not proceed with save
|
|
8204
|
+
return false;
|
|
8205
|
+
}
|
|
8206
|
+
// Use parsed object if available; default to {} when missing
|
|
8207
|
+
var parsed = (normResult.parsed || (newObj[jsonField.name] && typeof newObj[jsonField.name] == "object"
|
|
8208
|
+
? newObj[jsonField.name] : {}));
|
|
8209
|
+
newObj[jsonField.name] = parsed;
|
|
8210
|
+
}
|
|
8211
|
+
}
|
|
7997
8212
|
newObj.joeUpdated = new Date();
|
|
7998
8213
|
overwrites = overwrites || {};
|
|
7999
8214
|
var obj = $.extend(newObj,overwrites);
|
|
@@ -9764,6 +9979,13 @@ logit(intent)
|
|
|
9764
9979
|
url = prefix+response.Key;
|
|
9765
9980
|
}
|
|
9766
9981
|
var filename = response.Key.replace(self.current.object._id+'/','');
|
|
9982
|
+
// Stash OpenAI info for use during finalization
|
|
9983
|
+
_joe._lastOpenAI = _joe._lastOpenAI || {};
|
|
9984
|
+
_joe._lastOpenAI[response.Key] = {
|
|
9985
|
+
openai_file_id: response.openai_file_id,
|
|
9986
|
+
openai_purpose: response.openai_purpose,
|
|
9987
|
+
openai_error: response.openai_error
|
|
9988
|
+
};
|
|
9767
9989
|
if(field.url_field){
|
|
9768
9990
|
var nprop = {};
|
|
9769
9991
|
_joe.current.object[field.url_field] = url;
|
|
@@ -9788,6 +10010,53 @@ logit(intent)
|
|
|
9788
10010
|
file: { base64:data.base64, extension:data.extension, type:data.contentType, filename: (_joe.current.object._id+data.extension), name: (_joe.current.object._id+data.extension) },
|
|
9789
10011
|
field: data.field
|
|
9790
10012
|
}, callback);
|
|
10013
|
+
},
|
|
10014
|
+
// Retry uploading a specific file to OpenAI using its URL.
|
|
10015
|
+
// Invoked by the uploader row action.
|
|
10016
|
+
openaiRetryFromUrl:function(uploader_id, filename){
|
|
10017
|
+
try{
|
|
10018
|
+
var joe_uploader = self.uploaders[uploader_id];
|
|
10019
|
+
if(!joe_uploader){ return alert('Uploader not found'); }
|
|
10020
|
+
var file = joe_uploader.files.where({filename:filename})[0];
|
|
10021
|
+
if(!file){ return alert('File not found'); }
|
|
10022
|
+
if(!file.url){ return alert('No URL to upload to OpenAI'); }
|
|
10023
|
+
var btn = $(joe_uploader.preview).find("joe-uploader-openai-btn:contains('"+filename+"')");
|
|
10024
|
+
joe_uploader.message.append('<div>Uploading to OpenAI...</div>');
|
|
10025
|
+
$.ajax({
|
|
10026
|
+
url: (location.port && '//'+__jsc.hostname+':'+__jsc.port+'/API/plugin/chatgpt/filesRetryFromUrl/') || '//'+__jsc.hostname+'/API/plugin/chatgpt/filesRetryFromUrl/',
|
|
10027
|
+
type:'POST',
|
|
10028
|
+
data:{
|
|
10029
|
+
url:file.url,
|
|
10030
|
+
filename:file.filename,
|
|
10031
|
+
contentType:file.type
|
|
10032
|
+
},
|
|
10033
|
+
success:function(resp){
|
|
10034
|
+
if(resp && resp.success && resp.openai_file_id){
|
|
10035
|
+
file.openai_file_id = resp.openai_file_id;
|
|
10036
|
+
file.openai_purpose = resp.openai_purpose || 'assistants';
|
|
10037
|
+
file.openai_status = 'ok';
|
|
10038
|
+
file.openai_error = null;
|
|
10039
|
+
joe_uploader.message.append('<div>OpenAI file attached</div>');
|
|
10040
|
+
}else{
|
|
10041
|
+
file.openai_status = 'error';
|
|
10042
|
+
file.openai_error = (resp && resp.error) || 'Upload failed';
|
|
10043
|
+
joe_uploader.message.append('<div>OpenAI error: '+(file.openai_error)+'</div>');
|
|
10044
|
+
}
|
|
10045
|
+
// Refresh preview to reflect new status/button
|
|
10046
|
+
$(joe_uploader.preview).html(_renderUploaderFilePreviews(joe_uploader.files,joe_uploader.cuid));
|
|
10047
|
+
// Save object so file metadata is persisted
|
|
10048
|
+
self.updateObject(null, null, true);
|
|
10049
|
+
},
|
|
10050
|
+
error:function(xhr,status,err){
|
|
10051
|
+
var message = (xhr && (xhr.responseJSON && (xhr.responseJSON.error || xhr.responseJSON.code) || xhr.responseText)) || err || status || 'Retry failed';
|
|
10052
|
+
file.openai_status = 'error';
|
|
10053
|
+
file.openai_error = message;
|
|
10054
|
+
joe_uploader.message.append('<div>OpenAI error: '+message+'</div>');
|
|
10055
|
+
}
|
|
10056
|
+
});
|
|
10057
|
+
}catch(e){
|
|
10058
|
+
alert(e && e.message || e);
|
|
10059
|
+
}
|
|
9791
10060
|
}
|
|
9792
10061
|
},
|
|
9793
10062
|
ready:{
|
|
@@ -10685,7 +10954,9 @@ logit(intent)
|
|
|
10685
10954
|
/*-------------------------------------------------------------------->
|
|
10686
10955
|
//Colors
|
|
10687
10956
|
<--------------------------------------------------------------------*/
|
|
10688
|
-
this.Colors={
|
|
10957
|
+
this.Colors={
|
|
10958
|
+
"ai":"#0D9488"
|
|
10959
|
+
}
|
|
10689
10960
|
this.Colors.priority = {
|
|
10690
10961
|
1:'#cc4500',
|
|
10691
10962
|
2:'#FFee33',
|