total5 0.0.17-7 → 0.0.17-8

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/aimodel.js CHANGED
@@ -235,17 +235,167 @@ function createTool(id, name) {
235
235
  };
236
236
  }
237
237
 
238
+ function parseJSON(value) {
239
+ try {
240
+ return JSON.parse(value);
241
+ } catch (e) {
242
+ return null;
243
+ }
244
+ }
245
+
246
+ function createTool(id, name) {
247
+ return {
248
+ id: id || null,
249
+ name: name || null,
250
+ arguments: '',
251
+ input: null
252
+ };
253
+ }
254
+
255
+ function normalize(value) {
256
+
257
+ if (value == null)
258
+ return {};
259
+
260
+ if (typeof value === 'object')
261
+ return value;
262
+
263
+ if (typeof value !== 'string')
264
+ return value;
265
+
266
+ value = value.trim();
267
+
268
+ if (!value)
269
+ return {};
270
+
271
+ const json = parseJSON(value);
272
+
273
+ if (json)
274
+ return json;
275
+
276
+ return value;
277
+ }
278
+
279
+ function parseJSON(value) {
280
+ try {
281
+ return JSON.parse(value);
282
+ } catch (e) {
283
+ return null;
284
+ }
285
+ }
286
+
287
+ function createTool(id, name) {
288
+ return {
289
+ id: id || null,
290
+ name: name || null,
291
+ arguments: '',
292
+ input: null
293
+ };
294
+ }
295
+
296
+ function normalize(value) {
297
+
298
+ if (value == null)
299
+ return {};
300
+
301
+ if (typeof value === 'object')
302
+ return value;
303
+
304
+ if (typeof value !== 'string')
305
+ return value;
306
+
307
+ value = value.trim();
308
+
309
+ if (!value)
310
+ return {};
311
+
312
+ const json = parseJSON(value);
313
+
314
+ if (json)
315
+ return json;
316
+
317
+ return value;
318
+ }
319
+
238
320
  class AIStreamParser {
239
321
 
240
- constructor(provider) {
322
+ constructor(provider, ondata) {
241
323
  this.provider = provider || 'generic';
324
+
242
325
  this.content = '';
326
+ this.thinking = '';
243
327
  this.tools = [];
244
328
  this.reasoning = 'content';
329
+
245
330
  this.buffer = Buffer.alloc(0);
246
331
  this.toolmap = Object.create(null);
332
+
333
+ this.listeners = Object.create(null);
334
+ this.ondata = typeof ondata === 'function' ? ondata : null;
335
+
336
+ this.thinking_signature = null;
337
+ this.thought_signatures = [];
338
+ }
339
+
340
+ // ------------------------------------------------------------
341
+ // Events
342
+ // ------------------------------------------------------------
343
+
344
+ on(type, fn) {
345
+ if (!type || typeof fn !== 'function')
346
+ return this;
347
+
348
+ if (!this.listeners[type])
349
+ this.listeners[type] = [];
350
+
351
+ this.listeners[type].push(fn);
352
+ return this;
247
353
  }
248
354
 
355
+ off(type, fn) {
356
+ const arr = this.listeners[type];
357
+
358
+ if (!arr)
359
+ return this;
360
+
361
+ const index = arr.indexOf(fn);
362
+
363
+ if (index !== -1)
364
+ arr.splice(index, 1);
365
+
366
+ return this;
367
+ }
368
+
369
+ emit(type, data) {
370
+ const event = {
371
+ type,
372
+ ...data
373
+ };
374
+
375
+ if (this.ondata)
376
+ this.ondata(event);
377
+
378
+ const listeners = this.listeners[type];
379
+
380
+ if (listeners) {
381
+ for (const fn of listeners)
382
+ fn(event);
383
+ }
384
+
385
+ const all = this.listeners['*'];
386
+
387
+ if (all) {
388
+ for (const fn of all)
389
+ fn(event);
390
+ }
391
+
392
+ return event;
393
+ }
394
+
395
+ // ------------------------------------------------------------
396
+ // Public API
397
+ // ------------------------------------------------------------
398
+
249
399
  write(chunk) {
250
400
  if (chunk == null)
251
401
  return this.output();
@@ -265,11 +415,11 @@ class AIStreamParser {
265
415
 
266
416
  let index;
267
417
 
268
- while ((index = this.buffer.indexOf(0x0A)) !== -1) { // \n
418
+ while ((index = this.buffer.indexOf(0x0A)) !== -1) {
269
419
  let lineBuffer = this.buffer.subarray(0, index);
270
420
  this.buffer = this.buffer.subarray(index + 1);
271
421
 
272
- // CRLF support: remove \r
422
+ // CRLF support
273
423
  if (lineBuffer.length && lineBuffer[lineBuffer.length - 1] === 0x0D)
274
424
  lineBuffer = lineBuffer.subarray(0, lineBuffer.length - 1);
275
425
 
@@ -311,6 +461,7 @@ class AIStreamParser {
311
461
  return;
312
462
 
313
463
  const json = parseJSON(line);
464
+
314
465
  if (json)
315
466
  this.writeObject(json);
316
467
  }
@@ -318,9 +469,17 @@ class AIStreamParser {
318
469
  end() {
319
470
  if (this.buffer.length)
320
471
  this.processLineBuffer(this.buffer);
472
+
321
473
  this.buffer = Buffer.alloc(0);
322
474
  this.finalizeTools();
323
- return this.output();
475
+
476
+ const output = this.output();
477
+
478
+ this.emit('done', {
479
+ output
480
+ });
481
+
482
+ return output;
324
483
  }
325
484
 
326
485
  writeObject(chunk) {
@@ -328,17 +487,21 @@ class AIStreamParser {
328
487
  case 'ollama':
329
488
  this.parseOllama(chunk);
330
489
  break;
490
+
331
491
  case 'openai_chat':
332
492
  case 'openai':
333
493
  this.parseOpenAI(chunk);
334
494
  break;
495
+
335
496
  case 'openai_responses':
336
497
  this.parseOpenAIresponse(chunk);
337
498
  break;
499
+
338
500
  case 'claude':
339
501
  case 'anthropic':
340
502
  this.parseClaude(chunk);
341
503
  break;
504
+
342
505
  case 'gemini':
343
506
  case 'google':
344
507
  this.parseGemini(chunk);
@@ -348,26 +511,85 @@ class AIStreamParser {
348
511
  this.parseGeneric(chunk);
349
512
  break;
350
513
  }
514
+
351
515
  return this.output();
352
516
  }
353
517
 
518
+ // ------------------------------------------------------------
519
+ // Accumulators
520
+ // ------------------------------------------------------------
521
+
354
522
  addContent(value) {
355
523
  if (!value)
356
524
  return;
525
+
526
+ if (typeof value !== 'string')
527
+ value = String(value);
528
+
357
529
  this.content += value;
530
+
531
+ this.emit('content', {
532
+ delta: value,
533
+ content: this.content,
534
+ reasoning: 'content'
535
+ });
536
+
358
537
  if (!this.tools.length)
359
538
  this.reasoning = 'content';
360
539
  }
361
540
 
541
+ addThinking(value) {
542
+ if (!value)
543
+ return;
544
+
545
+ if (typeof value === 'object') {
546
+
547
+ if (Array.isArray(value)) {
548
+ for (const item of value)
549
+ this.addThinking(item);
550
+ return;
551
+ }
552
+
553
+ if (value.text != null)
554
+ value = value.text;
555
+ else if (value.summary != null)
556
+ value = value.summary;
557
+ else if (value.content != null)
558
+ value = value.content;
559
+ else if (value.value != null)
560
+ value = value.value;
561
+ else
562
+ value = JSON.stringify(value);
563
+ }
564
+
565
+ if (!value)
566
+ return;
567
+
568
+ if (typeof value !== 'string')
569
+ value = String(value);
570
+
571
+ this.thinking += value;
572
+ this.reasoning = 'thinking';
573
+
574
+ this.emit('thinking', {
575
+ delta: value,
576
+ thinking: this.thinking,
577
+ reasoning: 'thinking'
578
+ });
579
+ }
580
+
362
581
  getTool(key, id, name) {
363
582
 
364
583
  key = key || id || name || String(this.tools.length);
365
584
 
366
585
  let tool = this.toolmap[key];
586
+ let isnew = false;
587
+
367
588
  if (!tool) {
368
589
  tool = createTool(id, name);
369
590
  this.toolmap[key] = tool;
370
591
  this.tools.push(tool);
592
+ isnew = true;
371
593
  }
372
594
 
373
595
  if (id)
@@ -378,6 +600,11 @@ class AIStreamParser {
378
600
 
379
601
  this.reasoning = 'tool';
380
602
 
603
+ this.emit(isnew ? 'tool_start' : 'tool_update', {
604
+ tool: this.cloneTool(tool),
605
+ reasoning: 'tool'
606
+ });
607
+
381
608
  return tool;
382
609
  }
383
610
 
@@ -389,10 +616,36 @@ class AIStreamParser {
389
616
  if (typeof value === 'object') {
390
617
  tool.input = value;
391
618
  tool.arguments = JSON.stringify(value);
619
+
620
+ this.emit('tool_arguments', {
621
+ tool: this.cloneTool(tool),
622
+ delta: value,
623
+ arguments: tool.input,
624
+ reasoning: 'tool'
625
+ });
626
+
392
627
  return;
393
628
  }
394
629
 
630
+ if (typeof value !== 'string')
631
+ value = String(value);
632
+
395
633
  tool.arguments += value;
634
+
635
+ this.emit('tool_arguments', {
636
+ tool: this.cloneTool(tool),
637
+ delta: value,
638
+ arguments: tool.arguments,
639
+ reasoning: 'tool'
640
+ });
641
+ }
642
+
643
+ cloneTool(tool) {
644
+ return {
645
+ id: tool.id,
646
+ name: tool.name,
647
+ arguments: tool.input || normalize(tool.arguments)
648
+ };
396
649
  }
397
650
 
398
651
  finalizeTools() {
@@ -404,8 +657,10 @@ class AIStreamParser {
404
657
 
405
658
  output() {
406
659
  this.finalizeTools();
407
- return {
660
+
661
+ const output = {
408
662
  content: this.content,
663
+ thinking: this.thinking,
409
664
  tools: this.tools.map(tool => ({
410
665
  id: tool.id,
411
666
  name: tool.name,
@@ -413,6 +668,14 @@ class AIStreamParser {
413
668
  })),
414
669
  reasoning: this.tools.length ? 'tool' : this.reasoning
415
670
  };
671
+
672
+ if (this.thinking_signature)
673
+ output.thinking_signature = this.thinking_signature;
674
+
675
+ if (this.thought_signatures.length)
676
+ output.thought_signatures = this.thought_signatures;
677
+
678
+ return output;
416
679
  }
417
680
 
418
681
  // ------------------------------------------------------------
@@ -421,34 +684,80 @@ class AIStreamParser {
421
684
 
422
685
  parseOllama(chunk) {
423
686
 
687
+ // Ollama OpenAI-compatible endpoint fallback
688
+ if (chunk.choices) {
689
+ this.parseOpenAI(chunk);
690
+ return;
691
+ }
692
+
424
693
  const message = chunk.message || {};
425
694
 
695
+ // /api/chat thinking
696
+ if (message.thinking)
697
+ this.addThinking(message.thinking);
698
+
699
+ // /api/generate thinking
700
+ if (chunk.thinking)
701
+ this.addThinking(chunk.thinking);
702
+
703
+ // OpenAI-compatible / model-specific reasoning fields
704
+ if (message.reasoning_content)
705
+ this.addThinking(message.reasoning_content);
706
+
707
+ if (message.reasoning)
708
+ this.addThinking(message.reasoning);
709
+
710
+ if (message.reasoning_text)
711
+ this.addThinking(message.reasoning_text);
712
+
713
+ // /api/chat content
426
714
  if (message.content)
427
715
  this.addContent(message.content);
428
716
 
429
- const calls = message.tool_calls || [];
717
+ // /api/generate content
718
+ if (chunk.response)
719
+ this.addContent(chunk.response);
720
+
721
+ const calls = message.tool_calls || chunk.tool_calls || [];
430
722
 
431
723
  for (let i = 0; i < calls.length; i++) {
432
724
  const call = calls[i];
433
- const fn = call.function || {};
725
+ const fn = call.function || call;
434
726
  const key = call.id || fn.name || `ollama_${i}`;
435
727
 
436
728
  const tool = this.getTool(key, call.id, fn.name);
437
729
 
438
730
  if (fn.arguments != null)
439
731
  this.appendToolArguments(tool, fn.arguments);
732
+ else if (fn.args != null)
733
+ this.appendToolArguments(tool, fn.args);
734
+ else if (fn.input != null)
735
+ this.appendToolArguments(tool, fn.input);
440
736
  }
441
737
  }
442
738
 
443
739
  // ------------------------------------------------------------
444
740
  // OpenAI Chat Completions stream
445
741
  // ------------------------------------------------------------
742
+
446
743
  parseOpenAI(chunk) {
447
744
  const choices = chunk.choices || [];
448
745
 
449
746
  for (const choice of choices) {
450
747
  const delta = choice.delta || {};
451
748
 
749
+ if (delta.reasoning_content)
750
+ this.addThinking(delta.reasoning_content);
751
+
752
+ if (delta.reasoning)
753
+ this.addThinking(delta.reasoning);
754
+
755
+ if (delta.thinking)
756
+ this.addThinking(delta.thinking);
757
+
758
+ if (delta.reasoning_text)
759
+ this.addThinking(delta.reasoning_text);
760
+
452
761
  if (delta.content)
453
762
  this.addContent(delta.content);
454
763
 
@@ -473,11 +782,19 @@ class AIStreamParser {
473
782
 
474
783
  parseOpenAIresponse(chunk) {
475
784
  switch (chunk.type) {
785
+
476
786
  case 'response.output_text.delta':
477
787
  case 'response.refusal.delta':
478
788
  this.addContent(chunk.delta);
479
789
  break;
480
790
 
791
+ case 'response.reasoning_summary_text.delta':
792
+ case 'response.reasoning_text.delta':
793
+ case 'response.reasoning_summary.delta':
794
+ case 'response.reasoning.delta':
795
+ this.addThinking(chunk.delta);
796
+ break;
797
+
481
798
  case 'response.function_call_arguments.delta': {
482
799
  const key = chunk.item_id || chunk.call_id || `openai_response_${chunk.output_index || 0}`;
483
800
  const tool = this.getTool(key, chunk.call_id || chunk.item_id, chunk.name);
@@ -489,6 +806,17 @@ class AIStreamParser {
489
806
  case 'response.output_item.added': {
490
807
  const item = chunk.item || {};
491
808
 
809
+ if (item.type === 'reasoning') {
810
+ if (item.summary)
811
+ this.addThinking(item.summary);
812
+
813
+ if (item.content)
814
+ this.addThinking(item.content);
815
+
816
+ if (item.text)
817
+ this.addThinking(item.text);
818
+ }
819
+
492
820
  if (item.type === 'function_call') {
493
821
  const key = item.id || item.call_id;
494
822
  const tool = this.getTool(key, item.call_id || item.id, item.name);
@@ -503,6 +831,17 @@ class AIStreamParser {
503
831
  case 'response.output_item.done': {
504
832
  const item = chunk.item || {};
505
833
 
834
+ if (item.type === 'reasoning') {
835
+ if (item.summary)
836
+ this.addThinking(item.summary);
837
+
838
+ if (item.content)
839
+ this.addThinking(item.content);
840
+
841
+ if (item.text)
842
+ this.addThinking(item.text);
843
+ }
844
+
506
845
  if (item.type === 'function_call') {
507
846
  const key = item.id || item.call_id;
508
847
  const tool = this.getTool(key, item.call_id || item.id, item.name);
@@ -525,6 +864,11 @@ class AIStreamParser {
525
864
  case 'content_block_start': {
526
865
  const block = chunk.content_block || {};
527
866
 
867
+ if (block.type === 'thinking') {
868
+ if (block.thinking)
869
+ this.addThinking(block.thinking);
870
+ }
871
+
528
872
  if (block.type === 'tool_use') {
529
873
  const key = block.id || `claude_${chunk.index || 0}`;
530
874
  const tool = this.getTool(key, block.id, block.name);
@@ -539,6 +883,12 @@ class AIStreamParser {
539
883
  case 'content_block_delta': {
540
884
  const delta = chunk.delta || {};
541
885
 
886
+ if (delta.type === 'thinking_delta')
887
+ this.addThinking(delta.thinking);
888
+
889
+ if (delta.type === 'signature_delta')
890
+ this.thinking_signature = delta.signature;
891
+
542
892
  if (delta.type === 'text_delta')
543
893
  this.addContent(delta.text);
544
894
 
@@ -576,8 +926,15 @@ class AIStreamParser {
576
926
  for (let i = 0; i < parts.length; i++) {
577
927
  const part = parts[i];
578
928
 
579
- if (part.text)
580
- this.addContent(part.text);
929
+ if (part.thoughtSignature)
930
+ this.thought_signatures.push(part.thoughtSignature);
931
+
932
+ if (part.text) {
933
+ if (part.thought)
934
+ this.addThinking(part.text);
935
+ else
936
+ this.addContent(part.text);
937
+ }
581
938
 
582
939
  if (part.functionCall) {
583
940
  const fn = part.functionCall;
@@ -595,6 +952,31 @@ class AIStreamParser {
595
952
  // ------------------------------------------------------------
596
953
 
597
954
  parseGeneric(chunk) {
955
+
956
+ if (chunk.thinking)
957
+ this.addThinking(chunk.thinking);
958
+
959
+ if (chunk.reasoning)
960
+ this.addThinking(chunk.reasoning);
961
+
962
+ if (chunk.reasoning_content)
963
+ this.addThinking(chunk.reasoning_content);
964
+
965
+ if (chunk.reasoning_text)
966
+ this.addThinking(chunk.reasoning_text);
967
+
968
+ if (chunk.message?.thinking)
969
+ this.addThinking(chunk.message.thinking);
970
+
971
+ if (chunk.message?.reasoning)
972
+ this.addThinking(chunk.message.reasoning);
973
+
974
+ if (chunk.message?.reasoning_content)
975
+ this.addThinking(chunk.message.reasoning_content);
976
+
977
+ if (chunk.message?.reasoning_text)
978
+ this.addThinking(chunk.message.reasoning_text);
979
+
598
980
  if (chunk.content)
599
981
  this.addContent(chunk.content);
600
982
 
@@ -622,10 +1004,16 @@ class AIStreamParser {
622
1004
 
623
1005
  reset() {
624
1006
  this.content = '';
1007
+ this.thinking = '';
625
1008
  this.tools = [];
626
1009
  this.reasoning = 'content';
1010
+
627
1011
  this.buffer = Buffer.alloc(0);
628
1012
  this.toolmap = Object.create(null);
1013
+
1014
+ this.thinking_signature = null;
1015
+ this.thought_signatures = [];
1016
+
629
1017
  return this;
630
1018
  }
631
1019
  }
package/builders.js CHANGED
@@ -1339,6 +1339,12 @@ function ActionCaller() {
1339
1339
  setImmediate(ActionCallerExec, self);
1340
1340
  }
1341
1341
 
1342
+ ActionCaller.prototype.config = function(value) {
1343
+ this.options.config = value;
1344
+ return this;
1345
+ };
1346
+
1347
+
1342
1348
  ActionCaller.prototype.debug = function() {
1343
1349
  this.options.debug = true;
1344
1350
  return this;
@@ -1412,6 +1418,20 @@ ActionCaller.prototype.exec = function() {
1412
1418
  $.controller = self.controller;
1413
1419
  $.user = self.options.user;
1414
1420
  $.config = action.config || EMPTYOBJECT;
1421
+ if (self.options.config) {
1422
+
1423
+ if ($.config === EMPTYOBJECT)
1424
+ $.config = {};
1425
+ else {
1426
+ let tmp = $.config;
1427
+ $.config = {};
1428
+ for (let key in tmp)
1429
+ $.config[key] = tmp[key];
1430
+ }
1431
+
1432
+ for (let key in self.options.config)
1433
+ $.config[key] = self.options.config[key];
1434
+ }
1415
1435
 
1416
1436
  action.called++;
1417
1437
 
package/changelog.txt CHANGED
@@ -17,6 +17,10 @@
17
17
  - added `AIMODEL.tool(content, [merge])` method
18
18
  - added `AIPARSER(provider)` method for parsing AI responses
19
19
  - extended `String.prototype` by adding the `String.parseContext()` method to parse a specific text file format
20
+ - added `ACTION().config(obj)` method
21
+ - added a new property `flow.instance.repo = {}` for storing additional data for Flow node instances
22
+ - fixed `Utils.filestreamer()` method
23
+ - improved `Utils.filestreamer()` method by adding percentage
20
24
 
21
25
  ========================
22
26
  0.0.16
@@ -9,7 +9,7 @@ if (!global.F)
9
9
 
10
10
  const W = F.Worker;
11
11
  const Fork = F.Child.fork;
12
- const VERSION = 33;
12
+ const VERSION = 34;
13
13
  const NOTIFYPATH = '/notify/';
14
14
 
15
15
  var isFLOWSTREAMWORKER = false;
@@ -1939,6 +1939,7 @@ function MAKEFLOWSTREAM(meta) {
1939
1939
  tmp.offset = com.offset;
1940
1940
  tmp.size = com.size;
1941
1941
  tmp.meta = com.meta;
1942
+ tmp.repo = com.repo;
1942
1943
  tmp.schemaid = com.schemaid;
1943
1944
  tmp.note = com.note;
1944
1945
  tmp.schema = com.schema;
@@ -1994,6 +1995,7 @@ function MAKEFLOWSTREAM(meta) {
1994
1995
  data.design = design;
1995
1996
  data.variables = variables;
1996
1997
  data.sources = sources;
1998
+ data.flowstream = VERSION;
1997
1999
  return data;
1998
2000
  };
1999
2001
 
package/flowstream.js CHANGED
@@ -1486,6 +1486,13 @@ FP._use = function(schema, callback, reinit, insert) {
1486
1486
  fi.size = instance.size;
1487
1487
  fi.tab = instance.tab;
1488
1488
  fi.ts = ts;
1489
+
1490
+ // From the view of the designer is the "repo" not visible
1491
+ if (instance.repo)
1492
+ fi.repo = instance.repo;
1493
+ else if (!fi.repo)
1494
+ fi.repo = {};
1495
+
1489
1496
  if (JSON.stringify(fi.config) !== JSON.stringify(instance.config)) {
1490
1497
  F.TUtils.extend(fi.config, instance.config);
1491
1498
  fi.configure && fi.configure(fi.config);
@@ -1579,6 +1586,10 @@ FP.initcomponent = function(key, component) {
1579
1586
  instance.isinstance = true;
1580
1587
  instance.stats = { pending: 0, input: 0, output: 0, duration: 0, destroyed: 0 };
1581
1588
  instance.cache = {};
1589
+
1590
+ if (!instance.repo)
1591
+ instance.repo = {};
1592
+
1582
1593
  instance.id = key;
1583
1594
  instance.module = component;
1584
1595
  instance.ready = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total5",
3
- "version": "0.0.17-7",
3
+ "version": "0.0.17-8",
4
4
  "description": "Total.js framework v5",
5
5
  "main": "index.js",
6
6
  "directories": {
package/utils.js CHANGED
@@ -1627,30 +1627,49 @@ exports.aistreamer = function(online, onmessage) {
1627
1627
  };
1628
1628
  };
1629
1629
 
1630
- exports.filestreamer = function(filename, onbuffer, onend, size) {
1630
+ exports.filestreamer = function(filename, onbuffer, onend, size = 1024 * 16, offset = 0) {
1631
1631
 
1632
1632
  if (typeof(onend) === 'number') {
1633
1633
  size = onend;
1634
1634
  onend = null;
1635
1635
  }
1636
1636
 
1637
- var Fd = null;
1637
+ let Fd = null;
1638
+ let Stat = null;
1638
1639
 
1639
- var read = function(offset) {
1640
- var buffer = Buffer.alloc(size || (1024 * 16));
1640
+ const read = function(offset) {
1641
+ const buffer = Buffer.alloc(size);
1641
1642
  Total.Fs.read(Fd, buffer, 0, buffer.length, offset, function(err, bytes) {
1642
1643
  if (err || !bytes) {
1643
- onend && onend(err);
1644
1644
  Total.Fs.close(Fd, NOOP);
1645
+ onend && onend(err);
1645
1646
  } else {
1646
- onbuffer(buffer.length !== read ? buffer.slice(0, bytes) : buffer, next => read(offset + bytes));
1647
+ const buff = buffer.length !== read ? buffer.slice(0, bytes) : buffer;
1648
+ Stat.read += buff.length;
1649
+ onbuffer(buff, function(stop) {
1650
+ if (stop === true) {
1651
+ Total.Fs.close(Fd, NOOP);
1652
+ onend && onend();
1653
+ } else
1654
+ read(offset + bytes);
1655
+ }, (Stat.read * 100) / Stat.size);
1647
1656
  }
1648
1657
  });
1649
1658
  };
1650
1659
 
1651
- Total.Fs.open(filename, function(err, fd) {
1652
- Fd = fd;
1653
- read(0);
1660
+ Total.Fs.lstat(filename, function(err, stat) {
1661
+
1662
+ if (err) {
1663
+ onend && onend(err);
1664
+ return;
1665
+ }
1666
+
1667
+ Stat = stat;
1668
+ Total.Fs.open(filename, function(err, fd) {
1669
+ Fd = fd;
1670
+ Stat.read = offset;
1671
+ read(offset);
1672
+ });
1654
1673
  });
1655
1674
 
1656
1675
  };
@@ -6339,7 +6358,7 @@ function jsonschemaaitool(name) {
6339
6358
  let required = t.required;
6340
6359
  for (let key in t.properties) {
6341
6360
  let prop = t.properties[key];
6342
- properties[key] = { type: prop.type, description: t.errors[key] };
6361
+ properties[key] = { type: prop.type, description: t.errors ? (t.errors[key] || '') : '' };
6343
6362
  }
6344
6363
  return {
6345
6364
  type: 'function',