total5 0.0.17-5 → 0.0.17-7
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 +490 -2
- package/changelog.txt +3 -1
- package/global.js +2 -1
- package/package.json +1 -1
- package/utils.js +49 -1
package/aimodel.js
CHANGED
|
@@ -12,6 +12,7 @@ function AI(model) {
|
|
|
12
12
|
t.payload = {};
|
|
13
13
|
t.payload.model = model;
|
|
14
14
|
t.payload.messages = [];
|
|
15
|
+
t.payload.tools = [];
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
// Enables think mode
|
|
@@ -21,6 +22,10 @@ AI.prototype.think = function () {
|
|
|
21
22
|
return t;
|
|
22
23
|
};
|
|
23
24
|
|
|
25
|
+
AI.prototype.parser = function(provider) {
|
|
26
|
+
return parseAIStream(provider);
|
|
27
|
+
};
|
|
28
|
+
|
|
24
29
|
// Internal function
|
|
25
30
|
// Appends content message
|
|
26
31
|
AI.prototype.message = function(role, content, merge) {
|
|
@@ -78,8 +83,9 @@ AI.prototype.assistant = function(content, merge) {
|
|
|
78
83
|
return this.message('assistant', content, merge);
|
|
79
84
|
};
|
|
80
85
|
|
|
81
|
-
AI.prototype.tool = function(content
|
|
82
|
-
|
|
86
|
+
AI.prototype.tool = function(content) {
|
|
87
|
+
this.payload.tools.push(content);
|
|
88
|
+
return this;
|
|
83
89
|
};
|
|
84
90
|
|
|
85
91
|
AI.prototype.promise = function($) {
|
|
@@ -130,6 +136,48 @@ AI.prototype.run = function() {
|
|
|
130
136
|
return t;
|
|
131
137
|
};
|
|
132
138
|
|
|
139
|
+
function parseJSON(value) {
|
|
140
|
+
if (!value)
|
|
141
|
+
return null;
|
|
142
|
+
|
|
143
|
+
if (typeof value === 'object')
|
|
144
|
+
return value;
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
return JSON.parse(value);
|
|
148
|
+
} catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function normalize(value) {
|
|
154
|
+
|
|
155
|
+
if (value == null)
|
|
156
|
+
return {};
|
|
157
|
+
|
|
158
|
+
if (typeof(value) === 'object')
|
|
159
|
+
return value;
|
|
160
|
+
|
|
161
|
+
if (typeof(value) === 'string') {
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(value);
|
|
164
|
+
} catch {
|
|
165
|
+
return { _raw: value };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return { _raw: value };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function createTool(id, name) {
|
|
173
|
+
return {
|
|
174
|
+
id: id || null,
|
|
175
|
+
name: name || null,
|
|
176
|
+
arguments: '',
|
|
177
|
+
input: null
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
133
181
|
exports.exec = function(model) {
|
|
134
182
|
return new AI(model);
|
|
135
183
|
};
|
|
@@ -145,3 +193,443 @@ exports.newai = function(model, config, callback) {
|
|
|
145
193
|
for (const m of models)
|
|
146
194
|
F.aimodels[m] = { config, callback };
|
|
147
195
|
};
|
|
196
|
+
|
|
197
|
+
function parseJSON(value) {
|
|
198
|
+
if (!value)
|
|
199
|
+
return null;
|
|
200
|
+
|
|
201
|
+
if (typeof value === 'object')
|
|
202
|
+
return value;
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
return JSON.parse(value);
|
|
206
|
+
} catch {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function normalize(value) {
|
|
212
|
+
if (value == null)
|
|
213
|
+
return {};
|
|
214
|
+
|
|
215
|
+
if (typeof value === 'object')
|
|
216
|
+
return value;
|
|
217
|
+
|
|
218
|
+
if (typeof value === 'string') {
|
|
219
|
+
try {
|
|
220
|
+
return JSON.parse(value);
|
|
221
|
+
} catch {
|
|
222
|
+
return { _raw: value };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return { _raw: value };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function createTool(id, name) {
|
|
230
|
+
return {
|
|
231
|
+
id: id || null,
|
|
232
|
+
name: name || null,
|
|
233
|
+
arguments: '',
|
|
234
|
+
input: null
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
class AIStreamParser {
|
|
239
|
+
|
|
240
|
+
constructor(provider) {
|
|
241
|
+
this.provider = provider || 'generic';
|
|
242
|
+
this.content = '';
|
|
243
|
+
this.tools = [];
|
|
244
|
+
this.reasoning = 'content';
|
|
245
|
+
this.buffer = Buffer.alloc(0);
|
|
246
|
+
this.toolmap = Object.create(null);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
write(chunk) {
|
|
250
|
+
if (chunk == null)
|
|
251
|
+
return this.output();
|
|
252
|
+
|
|
253
|
+
if (chunk instanceof Buffer || typeof(chunk) === 'string' || chunk instanceof Uint8Array || chunk instanceof ArrayBuffer)
|
|
254
|
+
return this.writeBuffer(chunk);
|
|
255
|
+
|
|
256
|
+
if (typeof(chunk) === 'object')
|
|
257
|
+
return this.writeObject(chunk);
|
|
258
|
+
|
|
259
|
+
return this.output();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
writeBuffer(chunk) {
|
|
263
|
+
|
|
264
|
+
this.appendBuffer(chunk);
|
|
265
|
+
|
|
266
|
+
let index;
|
|
267
|
+
|
|
268
|
+
while ((index = this.buffer.indexOf(0x0A)) !== -1) { // \n
|
|
269
|
+
let lineBuffer = this.buffer.subarray(0, index);
|
|
270
|
+
this.buffer = this.buffer.subarray(index + 1);
|
|
271
|
+
|
|
272
|
+
// CRLF support: remove \r
|
|
273
|
+
if (lineBuffer.length && lineBuffer[lineBuffer.length - 1] === 0x0D)
|
|
274
|
+
lineBuffer = lineBuffer.subarray(0, lineBuffer.length - 1);
|
|
275
|
+
|
|
276
|
+
this.processLineBuffer(lineBuffer);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return this.output();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
appendBuffer(chunk) {
|
|
283
|
+
|
|
284
|
+
if (chunk == null)
|
|
285
|
+
return;
|
|
286
|
+
|
|
287
|
+
if (Buffer.isBuffer(chunk)) {
|
|
288
|
+
// OK
|
|
289
|
+
} else if (chunk instanceof Uint8Array) {
|
|
290
|
+
chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
291
|
+
} else if (chunk instanceof ArrayBuffer) {
|
|
292
|
+
chunk = Buffer.from(chunk);
|
|
293
|
+
} else {
|
|
294
|
+
chunk = Buffer.from(String(chunk), 'utf8');
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this.buffer = this.buffer.length ? Buffer.concat([this.buffer, chunk]) : chunk;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
processLineBuffer(lineBuffer) {
|
|
301
|
+
let line = lineBuffer.toString('utf8').trim();
|
|
302
|
+
|
|
303
|
+
if (!line)
|
|
304
|
+
return;
|
|
305
|
+
|
|
306
|
+
// SSE format: data: {...}
|
|
307
|
+
if (line.startsWith('data:'))
|
|
308
|
+
line = line.substring(5).trim();
|
|
309
|
+
|
|
310
|
+
if (!line || line === '[DONE]')
|
|
311
|
+
return;
|
|
312
|
+
|
|
313
|
+
const json = parseJSON(line);
|
|
314
|
+
if (json)
|
|
315
|
+
this.writeObject(json);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
end() {
|
|
319
|
+
if (this.buffer.length)
|
|
320
|
+
this.processLineBuffer(this.buffer);
|
|
321
|
+
this.buffer = Buffer.alloc(0);
|
|
322
|
+
this.finalizeTools();
|
|
323
|
+
return this.output();
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
writeObject(chunk) {
|
|
327
|
+
switch (this.provider) {
|
|
328
|
+
case 'ollama':
|
|
329
|
+
this.parseOllama(chunk);
|
|
330
|
+
break;
|
|
331
|
+
case 'openai_chat':
|
|
332
|
+
case 'openai':
|
|
333
|
+
this.parseOpenAI(chunk);
|
|
334
|
+
break;
|
|
335
|
+
case 'openai_responses':
|
|
336
|
+
this.parseOpenAIresponse(chunk);
|
|
337
|
+
break;
|
|
338
|
+
case 'claude':
|
|
339
|
+
case 'anthropic':
|
|
340
|
+
this.parseClaude(chunk);
|
|
341
|
+
break;
|
|
342
|
+
case 'gemini':
|
|
343
|
+
case 'google':
|
|
344
|
+
this.parseGemini(chunk);
|
|
345
|
+
break;
|
|
346
|
+
|
|
347
|
+
default:
|
|
348
|
+
this.parseGeneric(chunk);
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
return this.output();
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
addContent(value) {
|
|
355
|
+
if (!value)
|
|
356
|
+
return;
|
|
357
|
+
this.content += value;
|
|
358
|
+
if (!this.tools.length)
|
|
359
|
+
this.reasoning = 'content';
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
getTool(key, id, name) {
|
|
363
|
+
|
|
364
|
+
key = key || id || name || String(this.tools.length);
|
|
365
|
+
|
|
366
|
+
let tool = this.toolmap[key];
|
|
367
|
+
if (!tool) {
|
|
368
|
+
tool = createTool(id, name);
|
|
369
|
+
this.toolmap[key] = tool;
|
|
370
|
+
this.tools.push(tool);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (id)
|
|
374
|
+
tool.id = id;
|
|
375
|
+
|
|
376
|
+
if (name)
|
|
377
|
+
tool.name = name;
|
|
378
|
+
|
|
379
|
+
this.reasoning = 'tool';
|
|
380
|
+
|
|
381
|
+
return tool;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
appendToolArguments(tool, value) {
|
|
385
|
+
|
|
386
|
+
if (value == null)
|
|
387
|
+
return;
|
|
388
|
+
|
|
389
|
+
if (typeof value === 'object') {
|
|
390
|
+
tool.input = value;
|
|
391
|
+
tool.arguments = JSON.stringify(value);
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
tool.arguments += value;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
finalizeTools() {
|
|
399
|
+
for (const tool of this.tools) {
|
|
400
|
+
if (tool.input == null)
|
|
401
|
+
tool.input = normalize(tool.arguments);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
output() {
|
|
406
|
+
this.finalizeTools();
|
|
407
|
+
return {
|
|
408
|
+
content: this.content,
|
|
409
|
+
tools: this.tools.map(tool => ({
|
|
410
|
+
id: tool.id,
|
|
411
|
+
name: tool.name,
|
|
412
|
+
arguments: tool.input || normalize(tool.arguments)
|
|
413
|
+
})),
|
|
414
|
+
reasoning: this.tools.length ? 'tool' : this.reasoning
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ------------------------------------------------------------
|
|
419
|
+
// Ollama stream
|
|
420
|
+
// ------------------------------------------------------------
|
|
421
|
+
|
|
422
|
+
parseOllama(chunk) {
|
|
423
|
+
|
|
424
|
+
const message = chunk.message || {};
|
|
425
|
+
|
|
426
|
+
if (message.content)
|
|
427
|
+
this.addContent(message.content);
|
|
428
|
+
|
|
429
|
+
const calls = message.tool_calls || [];
|
|
430
|
+
|
|
431
|
+
for (let i = 0; i < calls.length; i++) {
|
|
432
|
+
const call = calls[i];
|
|
433
|
+
const fn = call.function || {};
|
|
434
|
+
const key = call.id || fn.name || `ollama_${i}`;
|
|
435
|
+
|
|
436
|
+
const tool = this.getTool(key, call.id, fn.name);
|
|
437
|
+
|
|
438
|
+
if (fn.arguments != null)
|
|
439
|
+
this.appendToolArguments(tool, fn.arguments);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// ------------------------------------------------------------
|
|
444
|
+
// OpenAI Chat Completions stream
|
|
445
|
+
// ------------------------------------------------------------
|
|
446
|
+
parseOpenAI(chunk) {
|
|
447
|
+
const choices = chunk.choices || [];
|
|
448
|
+
|
|
449
|
+
for (const choice of choices) {
|
|
450
|
+
const delta = choice.delta || {};
|
|
451
|
+
|
|
452
|
+
if (delta.content)
|
|
453
|
+
this.addContent(delta.content);
|
|
454
|
+
|
|
455
|
+
const calls = delta.tool_calls || [];
|
|
456
|
+
|
|
457
|
+
for (const call of calls) {
|
|
458
|
+
const index = call.index != null ? call.index : 0;
|
|
459
|
+
const fn = call.function || {};
|
|
460
|
+
const key = call.id || `openai_chat_${index}`;
|
|
461
|
+
|
|
462
|
+
const tool = this.getTool(key, call.id, fn.name);
|
|
463
|
+
|
|
464
|
+
if (fn.arguments != null)
|
|
465
|
+
this.appendToolArguments(tool, fn.arguments);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// ------------------------------------------------------------
|
|
471
|
+
// OpenAI Responses API stream
|
|
472
|
+
// ------------------------------------------------------------
|
|
473
|
+
|
|
474
|
+
parseOpenAIresponse(chunk) {
|
|
475
|
+
switch (chunk.type) {
|
|
476
|
+
case 'response.output_text.delta':
|
|
477
|
+
case 'response.refusal.delta':
|
|
478
|
+
this.addContent(chunk.delta);
|
|
479
|
+
break;
|
|
480
|
+
|
|
481
|
+
case 'response.function_call_arguments.delta': {
|
|
482
|
+
const key = chunk.item_id || chunk.call_id || `openai_response_${chunk.output_index || 0}`;
|
|
483
|
+
const tool = this.getTool(key, chunk.call_id || chunk.item_id, chunk.name);
|
|
484
|
+
|
|
485
|
+
this.appendToolArguments(tool, chunk.delta);
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
case 'response.output_item.added': {
|
|
490
|
+
const item = chunk.item || {};
|
|
491
|
+
|
|
492
|
+
if (item.type === 'function_call') {
|
|
493
|
+
const key = item.id || item.call_id;
|
|
494
|
+
const tool = this.getTool(key, item.call_id || item.id, item.name);
|
|
495
|
+
|
|
496
|
+
if (item.arguments)
|
|
497
|
+
this.appendToolArguments(tool, item.arguments);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
case 'response.output_item.done': {
|
|
504
|
+
const item = chunk.item || {};
|
|
505
|
+
|
|
506
|
+
if (item.type === 'function_call') {
|
|
507
|
+
const key = item.id || item.call_id;
|
|
508
|
+
const tool = this.getTool(key, item.call_id || item.id, item.name);
|
|
509
|
+
|
|
510
|
+
if (item.arguments)
|
|
511
|
+
this.appendToolArguments(tool, item.arguments);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// ------------------------------------------------------------
|
|
520
|
+
// Claude / Anthropic stream
|
|
521
|
+
// ------------------------------------------------------------
|
|
522
|
+
|
|
523
|
+
parseClaude(chunk) {
|
|
524
|
+
switch (chunk.type) {
|
|
525
|
+
case 'content_block_start': {
|
|
526
|
+
const block = chunk.content_block || {};
|
|
527
|
+
|
|
528
|
+
if (block.type === 'tool_use') {
|
|
529
|
+
const key = block.id || `claude_${chunk.index || 0}`;
|
|
530
|
+
const tool = this.getTool(key, block.id, block.name);
|
|
531
|
+
|
|
532
|
+
if (block.input)
|
|
533
|
+
this.appendToolArguments(tool, block.input);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
case 'content_block_delta': {
|
|
540
|
+
const delta = chunk.delta || {};
|
|
541
|
+
|
|
542
|
+
if (delta.type === 'text_delta')
|
|
543
|
+
this.addContent(delta.text);
|
|
544
|
+
|
|
545
|
+
if (delta.type === 'input_json_delta') {
|
|
546
|
+
const key = `claude_${chunk.index || 0}`;
|
|
547
|
+
const tool = this.getTool(key, null, null);
|
|
548
|
+
|
|
549
|
+
this.appendToolArguments(tool, delta.partial_json);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
case 'message_delta': {
|
|
556
|
+
const delta = chunk.delta || {};
|
|
557
|
+
|
|
558
|
+
if (delta.stop_reason === 'tool_use')
|
|
559
|
+
this.reasoning = 'tool';
|
|
560
|
+
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// ------------------------------------------------------------
|
|
567
|
+
// Gemini stream
|
|
568
|
+
// ------------------------------------------------------------
|
|
569
|
+
|
|
570
|
+
parseGemini(chunk) {
|
|
571
|
+
const candidates = chunk.candidates || [];
|
|
572
|
+
|
|
573
|
+
for (const candidate of candidates) {
|
|
574
|
+
const parts = candidate.content?.parts || [];
|
|
575
|
+
|
|
576
|
+
for (let i = 0; i < parts.length; i++) {
|
|
577
|
+
const part = parts[i];
|
|
578
|
+
|
|
579
|
+
if (part.text)
|
|
580
|
+
this.addContent(part.text);
|
|
581
|
+
|
|
582
|
+
if (part.functionCall) {
|
|
583
|
+
const fn = part.functionCall;
|
|
584
|
+
const key = `gemini_${i}_${fn.name}`;
|
|
585
|
+
|
|
586
|
+
const tool = this.getTool(key, key, fn.name);
|
|
587
|
+
this.appendToolArguments(tool, fn.args || {});
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// ------------------------------------------------------------
|
|
594
|
+
// Fallback parser
|
|
595
|
+
// ------------------------------------------------------------
|
|
596
|
+
|
|
597
|
+
parseGeneric(chunk) {
|
|
598
|
+
if (chunk.content)
|
|
599
|
+
this.addContent(chunk.content);
|
|
600
|
+
|
|
601
|
+
if (chunk.text)
|
|
602
|
+
this.addContent(chunk.text);
|
|
603
|
+
|
|
604
|
+
if (chunk.message?.content)
|
|
605
|
+
this.addContent(chunk.message.content);
|
|
606
|
+
|
|
607
|
+
const calls = chunk.tool_calls || chunk.tools || chunk.message?.tool_calls || [];
|
|
608
|
+
|
|
609
|
+
for (let i = 0; i < calls.length; i++) {
|
|
610
|
+
const call = calls[i];
|
|
611
|
+
const fn = call.function || call;
|
|
612
|
+
|
|
613
|
+
const tool = this.getTool(
|
|
614
|
+
call.id || `generic_${i}`,
|
|
615
|
+
call.id,
|
|
616
|
+
fn.name
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
this.appendToolArguments(tool, fn.arguments || fn.args || fn.input || {});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
reset() {
|
|
624
|
+
this.content = '';
|
|
625
|
+
this.tools = [];
|
|
626
|
+
this.reasoning = 'content';
|
|
627
|
+
this.buffer = Buffer.alloc(0);
|
|
628
|
+
this.toolmap = Object.create(null);
|
|
629
|
+
return this;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
exports.parser = function(provider) {
|
|
634
|
+
return new AIStreamParser(provider);
|
|
635
|
+
};
|
package/changelog.txt
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
- fixed typo in send method data assignment
|
|
15
15
|
- added `PROXYCLIENT(proxyserver, ip:port, [logger])` method
|
|
16
16
|
- added `PROXYSERVER(endpoint, socketendpoint, [logger])` method
|
|
17
|
-
- added `AIMODEL.tool(content, [merge])` method
|
|
17
|
+
- added `AIMODEL.tool(content, [merge])` method
|
|
18
|
+
- added `AIPARSER(provider)` method for parsing AI responses
|
|
19
|
+
- extended `String.prototype` by adding the `String.parseContext()` method to parse a specific text file format
|
|
18
20
|
|
|
19
21
|
========================
|
|
20
22
|
0.0.16
|
package/global.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Total.js Globals
|
|
2
2
|
// The MIT License
|
|
3
|
-
// Copyright 2023 (c) Peter Širka <petersirka@gmail.com>
|
|
3
|
+
// Copyright 2023-2026 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
@@ -266,6 +266,7 @@ global.NEWAPI = (name, config, callback) => F.TApi.newapi(name, config, callback
|
|
|
266
266
|
|
|
267
267
|
// AI
|
|
268
268
|
global.AIMODEL = (name, schema, data, $) => F.TAIModel.exec(name, schema, data, $);
|
|
269
|
+
global.AIPARSER = (provider) => F.TAIModel.parser(provider);
|
|
269
270
|
global.NEWAIMODEL = (name, config, callback) => F.TAIModel.newai(name, config, callback);
|
|
270
271
|
|
|
271
272
|
// NoSQL
|
package/package.json
CHANGED
package/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Total.js Utils
|
|
2
2
|
// The MIT License
|
|
3
|
-
// Copyright 2012-
|
|
3
|
+
// Copyright 2012-2026 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
@@ -6051,6 +6051,31 @@ function extractnested(str, minDepth = 0) {
|
|
|
6051
6051
|
return { text: out, parts };
|
|
6052
6052
|
}
|
|
6053
6053
|
|
|
6054
|
+
SP.parseContext = function() {
|
|
6055
|
+
|
|
6056
|
+
const text = this;
|
|
6057
|
+
const REG = /-{20,}\s*\n([\s\S]*?)\n-{20,}\s*\n([\s\S]*?)(?=\n-{20,}\s*\n|$)/g;
|
|
6058
|
+
const output = [];
|
|
6059
|
+
|
|
6060
|
+
let match;
|
|
6061
|
+
|
|
6062
|
+
while ((match = REG.exec(text))) {
|
|
6063
|
+
const header = {};
|
|
6064
|
+
const body = match[2].trim();
|
|
6065
|
+
for (const line of match[1].split('\n')) {
|
|
6066
|
+
const index = line.indexOf(':');
|
|
6067
|
+
if (index === -1)
|
|
6068
|
+
continue;
|
|
6069
|
+
const key = line.substring(0, index).trim().toLowerCase();
|
|
6070
|
+
const value = line.substring(index + 1).trim();
|
|
6071
|
+
header[key] = value;
|
|
6072
|
+
}
|
|
6073
|
+
output.push({ ...header, body });
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
return output;
|
|
6077
|
+
};
|
|
6078
|
+
|
|
6054
6079
|
SP.toJSONSchema = SP.parseSchema = function(name, url) {
|
|
6055
6080
|
|
|
6056
6081
|
let obj = {};
|
|
@@ -6293,6 +6318,7 @@ SP.toJSONSchema = SP.parseSchema = function(name, url) {
|
|
|
6293
6318
|
obj.required = required;
|
|
6294
6319
|
|
|
6295
6320
|
obj.errors = errors;
|
|
6321
|
+
obj.aitool = jsonschemaaitool;
|
|
6296
6322
|
obj.transform = exports.jsonschematransform;
|
|
6297
6323
|
obj.validate = function(value, partial, path) {
|
|
6298
6324
|
let err = new F.TBuilders.ErrorBuilder();
|
|
@@ -6307,6 +6333,28 @@ SP.toJSONSchema = SP.parseSchema = function(name, url) {
|
|
|
6307
6333
|
return obj;
|
|
6308
6334
|
};
|
|
6309
6335
|
|
|
6336
|
+
function jsonschemaaitool(name) {
|
|
6337
|
+
let t = this;
|
|
6338
|
+
let properties = {};
|
|
6339
|
+
let required = t.required;
|
|
6340
|
+
for (let key in t.properties) {
|
|
6341
|
+
let prop = t.properties[key];
|
|
6342
|
+
properties[key] = { type: prop.type, description: t.errors[key] };
|
|
6343
|
+
}
|
|
6344
|
+
return {
|
|
6345
|
+
type: 'function',
|
|
6346
|
+
function: {
|
|
6347
|
+
name: name,
|
|
6348
|
+
description: t.summary || t.description,
|
|
6349
|
+
parameters: {
|
|
6350
|
+
type: 'object',
|
|
6351
|
+
properties: properties,
|
|
6352
|
+
required: required || []
|
|
6353
|
+
}
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6356
|
+
}
|
|
6357
|
+
|
|
6310
6358
|
exports.jsonschematransform = function(value, partial, error, path) {
|
|
6311
6359
|
|
|
6312
6360
|
let self = this;
|