tune-sdk 0.1.11 → 0.1.13
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/bin/cli.js +122 -104
- package/dist/fsctx.js +51 -1
- package/dist/rpc.js +211 -0
- package/dist/tune.js +3 -3
- package/package.json +4 -1
- package/tools/default.ctx.js +7 -42
- package/tools/groq_whisper.schema.json +48 -0
- package/tools/groq_whisper.tool.mjs +59 -0
- package/tools/openai_stt.schema.json +49 -0
- package/tools/openai_stt.tool.mjs +66 -0
package/bin/cli.js
CHANGED
|
@@ -1,115 +1,133 @@
|
|
|
1
|
-
|
|
1
|
+
var tune, rpc;
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
function parseArgs(args) {
|
|
4
|
+
var curKey, res, res1, key, value, _ref, _len;
|
|
5
|
+
var curKey;
|
|
6
|
+
curKey = null;
|
|
7
|
+
var res;
|
|
8
|
+
res = args.reduce((function(memo, arg) {
|
|
9
|
+
var key, value, _ref, _i;
|
|
10
|
+
if (arg.startsWith("--")) {
|
|
11
|
+
_ref = arg.substring(2)
|
|
12
|
+
.split("=");
|
|
13
|
+
key = _ref[0];
|
|
14
|
+
value = _ref[1];
|
|
15
|
+
if (!!value) {
|
|
16
|
+
memo[key] = value;
|
|
17
|
+
curKey = null;
|
|
18
|
+
} else {
|
|
19
|
+
curKey = key;
|
|
20
|
+
memo[key] = true;
|
|
21
|
+
}
|
|
22
|
+
} else if (curKey) {
|
|
23
|
+
memo[curKey] = arg;
|
|
24
|
+
curKey = null;
|
|
25
|
+
}
|
|
26
|
+
return memo;
|
|
27
|
+
}), {});
|
|
28
|
+
var res1;
|
|
29
|
+
res1 = {};
|
|
30
|
+
_ref = res;
|
|
31
|
+
for (key in _ref) {
|
|
32
|
+
value = _ref[key];
|
|
33
|
+
if (key.startsWith("set-")) {
|
|
34
|
+
res1.params = res1.params || {}
|
|
35
|
+
res1.params[key.substr(4)] = value;
|
|
13
36
|
} else {
|
|
14
|
-
|
|
15
|
-
args[currentKey] = true
|
|
37
|
+
res1[key] = value;
|
|
16
38
|
}
|
|
17
|
-
} else if (currentKey) {
|
|
18
|
-
args[currentKey] = arg;
|
|
19
|
-
currentKey = null;
|
|
20
39
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
return res1;
|
|
41
|
+
}
|
|
42
|
+
parseArgs;
|
|
43
|
+
tune = require("../dist/tune.js");
|
|
44
|
+
rpc = require("../dist/rpc.js");
|
|
45
|
+
async function rpc(args, ctx) {
|
|
46
|
+
var server;
|
|
47
|
+
var server;
|
|
48
|
+
return (server = jsonrpc());
|
|
49
|
+
}
|
|
50
|
+
rpc;
|
|
51
|
+
async function run(args, ctx) {
|
|
52
|
+
var stopVal, params;
|
|
53
|
+
var stopVal;
|
|
54
|
+
stopVal = args.stop || "assistant";
|
|
55
|
+
if ((stopVal !== "step" && stopVal !== "assistant")) stopVal = (function(msgs) {
|
|
56
|
+
var lastMsg;
|
|
57
|
+
if (!msgs.length) return false;
|
|
58
|
+
var lastMsg;
|
|
59
|
+
lastMsg = msgs["slice"](-1)[0];
|
|
60
|
+
if (!lastMsg.content) return false;
|
|
61
|
+
return (-1 !== lastMsg.content.inexOf(args.stop || "assistant"));
|
|
62
|
+
});
|
|
63
|
+
var params;
|
|
64
|
+
params = args.params;
|
|
65
|
+
delete args.params;
|
|
66
|
+
return ctx.file2run(args, params);
|
|
67
|
+
}
|
|
68
|
+
run;
|
|
28
69
|
async function main() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
var dirs, args, ctx, dir, ctxName, ext, module, m, _i, _res, _ref, _len, _ref0, _i0, _res0, _ref1, _len0, _ref2;
|
|
71
|
+
var dirs;
|
|
72
|
+
var args;
|
|
73
|
+
dirs = [];
|
|
74
|
+
args = parseArgs(process.argv.slice(2));
|
|
75
|
+
if (args.path) {
|
|
76
|
+
dirs = args.path.split(path.delimiter);
|
|
77
|
+
} else {
|
|
78
|
+
if (process.env.TUNE_PATH) dirs = process.env.TUNE_PATH.split(path.delimiter);
|
|
79
|
+
dirs.push(process.cwd());
|
|
80
|
+
}
|
|
81
|
+
ctx = tune.makeContext(process.env);
|
|
82
|
+
_res = [];
|
|
83
|
+
_ref = dirs;
|
|
84
|
+
for (_i = 0, _len = _ref.length; _i < _len; ++_i) {
|
|
85
|
+
dir = _ref[_i];
|
|
86
|
+
var ctxName;
|
|
87
|
+
ctxName = ["default.ctx.js", "default.ctx.cjs", "default.ctx.mjs"]
|
|
88
|
+
.map((function(name) {
|
|
89
|
+
return path.join(dir, name);
|
|
90
|
+
}))
|
|
91
|
+
.find((function(name) {
|
|
92
|
+
return fs.existsSync(name);
|
|
93
|
+
}));
|
|
94
|
+
if (!ctxName) continue;
|
|
95
|
+
var ext;
|
|
96
|
+
var module;
|
|
97
|
+
ext = path.extname(filename);
|
|
98
|
+
module = null;
|
|
99
|
+
if ((ext === ".js" || ext === ".cjs")) {
|
|
100
|
+
module = require(ctxName);
|
|
101
|
+
} else {
|
|
102
|
+
module = await import(ctxName);
|
|
103
|
+
module = module.default;
|
|
60
104
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
module = module.default;
|
|
74
|
-
}
|
|
75
|
-
if (typeof module === "function") {
|
|
76
|
-
ctx.use(module);
|
|
77
|
-
} else if (Array.isArray(module)) {
|
|
78
|
-
for (const m of module) {
|
|
79
|
-
if (typeof m === "function") {
|
|
80
|
-
ctx.use(m)
|
|
81
|
-
} else {
|
|
82
|
-
throw(Error(`err: Context file export is not an array of functions or function ${filename}`))
|
|
83
|
-
}
|
|
105
|
+
if ((typeof module === "function")) {
|
|
106
|
+
_ref0 = ctx.use(module);
|
|
107
|
+
} else if (Array.isArray(module)) {
|
|
108
|
+
_res0 = [];
|
|
109
|
+
_ref1 = module;
|
|
110
|
+
for (_i0 = 0, _len0 = _ref1.length; _i0 < _len0; ++_i0) {
|
|
111
|
+
m = _ref1[_i0];
|
|
112
|
+
if ((typeof m === "function")) {
|
|
113
|
+
_ref2 = ctx.use(module);
|
|
114
|
+
} else {
|
|
115
|
+
_ref2 = undefined;
|
|
116
|
+
throw Error(tpl("err: Context file export is not an array of functions or function {}", ctxName));
|
|
84
117
|
}
|
|
85
|
-
|
|
86
|
-
throw(Error(`err: Context file export is not an array of functions or function ${filename}`))
|
|
118
|
+
if (typeof _ref2 !== 'undefined') _res0.push(_ref2);
|
|
87
119
|
}
|
|
120
|
+
_ref0 = _res0;
|
|
121
|
+
} else {
|
|
122
|
+
_ref0 = undefined;
|
|
123
|
+
throw Error(tpl("err: Context file export is not an array of functions or function {}", ctxName));
|
|
88
124
|
}
|
|
89
|
-
|
|
90
|
-
if (stopVal !== "step" && stopVal != "assistant") {
|
|
91
|
-
stopVal = function(msgs) {
|
|
92
|
-
if (!msgs.length) return false
|
|
93
|
-
const lastMsg = msgs[msgs.length - 1]
|
|
94
|
-
if (!lastMsg.content) return false
|
|
95
|
-
return (lastMsg.content.indexOf(args.stop) !== -1)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let res = await tune.text2run(chat, ctx, { stop: stopVal })
|
|
100
|
-
|
|
101
|
-
const longFormatRegex = /^(system|user|tool_call|tool_result|assistant|error):/;
|
|
102
|
-
res = tune.msg2text(res, longFormatRegex.test(chat))
|
|
103
|
-
if (args.filename && args.save) {
|
|
104
|
-
chat += "\n" + res
|
|
105
|
-
fs.writeFileSync(args.filename, chat)
|
|
106
|
-
}
|
|
107
|
-
if (!args.save) {
|
|
108
|
-
console.log(res)
|
|
109
|
-
}
|
|
110
|
-
} catch (e) {
|
|
111
|
-
console.error(e)
|
|
125
|
+
if (typeof _ref0 !== 'undefined') _res.push(_ref0);
|
|
112
126
|
}
|
|
127
|
+
return _res;
|
|
113
128
|
}
|
|
114
|
-
|
|
115
|
-
|
|
129
|
+
main;
|
|
130
|
+
exports.parseArgs = parseArgs;
|
|
131
|
+
exports.rpc = rpc;
|
|
132
|
+
exports.main = main;
|
|
133
|
+
exports.run = run;
|
package/dist/fsctx.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var path, tune, envmd, TuneError, text2run, file2run;
|
|
1
|
+
var path, tune, fs, envmd, TuneError, text2run, file2run;
|
|
2
2
|
|
|
3
3
|
function extend() {
|
|
4
4
|
var _i;
|
|
@@ -616,6 +616,7 @@ if (typeof window !== "undefined") {
|
|
|
616
616
|
}
|
|
617
617
|
path = require("path");
|
|
618
618
|
tune = require("./tune");
|
|
619
|
+
fs = require("fs");
|
|
619
620
|
envmd = tune.envmd;
|
|
620
621
|
TuneError = tune.TuneError;
|
|
621
622
|
text2run = tune.text2run;
|
|
@@ -1062,6 +1063,53 @@ function fsMix(paths, opts, fs) {
|
|
|
1062
1063
|
});
|
|
1063
1064
|
}
|
|
1064
1065
|
fsMix;
|
|
1066
|
+
async function curFile(name, params) {
|
|
1067
|
+
var filename, value, _ref;
|
|
1068
|
+
if ((!this.stack || !this.stack.length)) return;
|
|
1069
|
+
filename = this.stack[0].filename;
|
|
1070
|
+
switch (name) {
|
|
1071
|
+
case "__filename":
|
|
1072
|
+
_ref = filename;
|
|
1073
|
+
break;
|
|
1074
|
+
case "__dirname":
|
|
1075
|
+
_ref = path.dirname(filename);
|
|
1076
|
+
break;
|
|
1077
|
+
case "__basename":
|
|
1078
|
+
_ref = path.basename(filename);
|
|
1079
|
+
break;
|
|
1080
|
+
case "__name":
|
|
1081
|
+
_ref = path.parse(filename).name;
|
|
1082
|
+
break;
|
|
1083
|
+
case "__ext":
|
|
1084
|
+
_ref = path.parse(filename).ext;
|
|
1085
|
+
break;
|
|
1086
|
+
default:
|
|
1087
|
+
_ref = undefined;
|
|
1088
|
+
}
|
|
1089
|
+
value = _ref;
|
|
1090
|
+
return (value ? {
|
|
1091
|
+
type: "text",
|
|
1092
|
+
read: (async function() {
|
|
1093
|
+
return value;
|
|
1094
|
+
})
|
|
1095
|
+
} : undefined);
|
|
1096
|
+
}
|
|
1097
|
+
curFile;
|
|
1098
|
+
|
|
1099
|
+
function defaultWrite(opts) {
|
|
1100
|
+
async function write(filename, data) {
|
|
1101
|
+
var directory;
|
|
1102
|
+
var directory;
|
|
1103
|
+
directory = path.dirname(filename);
|
|
1104
|
+
fs.mkdirSync(directory, {
|
|
1105
|
+
recursive: true
|
|
1106
|
+
});
|
|
1107
|
+
fs.writeFileSync(filename, data);
|
|
1108
|
+
return true;
|
|
1109
|
+
}
|
|
1110
|
+
return write;
|
|
1111
|
+
}
|
|
1112
|
+
defaultWrite;
|
|
1065
1113
|
|
|
1066
1114
|
function tpl(str) {
|
|
1067
1115
|
var _i;
|
|
@@ -1086,4 +1134,6 @@ exports.runFile = runFile;
|
|
|
1086
1134
|
exports.fsMix = fsMix;
|
|
1087
1135
|
exports.fsMod = fsMod;
|
|
1088
1136
|
exports.fsText = fsText;
|
|
1137
|
+
exports.defaultWrite = defaultWrite;
|
|
1138
|
+
exports.curFile = curFile;
|
|
1089
1139
|
exports.pparse = pparse;
|
package/dist/rpc.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
function AsyncIter() {
|
|
2
|
+
return (this[Symbol.asyncIterator] = this);
|
|
3
|
+
}
|
|
4
|
+
AsyncIter;
|
|
5
|
+
AsyncIter.prototype.next = (async function() {
|
|
6
|
+
var self, result;
|
|
7
|
+
var self;
|
|
8
|
+
self = this;
|
|
9
|
+
await _once((function() {
|
|
10
|
+
return (!!self.err || !!self.result);
|
|
11
|
+
}), (function() {
|
|
12
|
+
return undefined;
|
|
13
|
+
}));
|
|
14
|
+
var result;
|
|
15
|
+
result = self.result;
|
|
16
|
+
self.result = undefined;
|
|
17
|
+
if (self.err) throw self.err;
|
|
18
|
+
return result;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
function jsonrpc(params, exports) {
|
|
22
|
+
var client;
|
|
23
|
+
var client;
|
|
24
|
+
client = new JSONRPC(params, exports);
|
|
25
|
+
return new Proxy({}, {
|
|
26
|
+
get: (function(target, prop, receiver) {
|
|
27
|
+
return (function(params, stream) {
|
|
28
|
+
return client._call(prop, params, stream);
|
|
29
|
+
});
|
|
30
|
+
}),
|
|
31
|
+
set: (function(obj, prop, value) {
|
|
32
|
+
return (client[prop] = value);
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
jsonrpc;
|
|
37
|
+
|
|
38
|
+
function concatU8A(u8arrays) {
|
|
39
|
+
var totalLen, res, offset, arr, _i, _ref, _len;
|
|
40
|
+
var totalLen;
|
|
41
|
+
var res;
|
|
42
|
+
var offset;
|
|
43
|
+
totalLen = u8arrays.reduce((function(acc, arr) {
|
|
44
|
+
return (acc + arr.length);
|
|
45
|
+
}), 0);
|
|
46
|
+
res = new Uint8Array(totalLen);
|
|
47
|
+
offset = 0;
|
|
48
|
+
_ref = u8arrays;
|
|
49
|
+
for (_i = 0, _len = _ref.length; _i < _len; ++_i) {
|
|
50
|
+
arr = _ref[_i];
|
|
51
|
+
res.set(arr, offset);
|
|
52
|
+
offset = offset + arr.length;
|
|
53
|
+
}
|
|
54
|
+
return res;
|
|
55
|
+
}
|
|
56
|
+
concatU8A;
|
|
57
|
+
|
|
58
|
+
function JSONRPC(params, exports) {
|
|
59
|
+
var self;
|
|
60
|
+
this.msgId = 1;
|
|
61
|
+
this.chunks = [];
|
|
62
|
+
this.debug = params.debug;
|
|
63
|
+
this.name = params.name;
|
|
64
|
+
this.exports = exports || params.exports || {}
|
|
65
|
+
this.callbacks = {};
|
|
66
|
+
this.iterators = {};
|
|
67
|
+
this.reader = params.inStream.getReader();
|
|
68
|
+
this.writer = params.outStream.getWriter();
|
|
69
|
+
self = this;
|
|
70
|
+
this.decoder = new TextDecoder();
|
|
71
|
+
assert.ok(params.inStream, "inStream has to be defined and be a ReadableStream");
|
|
72
|
+
assert.ok(params.outStream, "outStream has to be defined and be a WritableStream");
|
|
73
|
+
async function pump() {
|
|
74
|
+
var res, value, done, buf, newlineIdx, line, msg, cb, iter, err, m, r, chunk, _res, _ref, _ref0;
|
|
75
|
+
var res;
|
|
76
|
+
res = await self.reader.read();
|
|
77
|
+
var value;
|
|
78
|
+
var done;
|
|
79
|
+
value = res.value;
|
|
80
|
+
done = res.done;
|
|
81
|
+
if (done) return;
|
|
82
|
+
self.chunks.push(value);
|
|
83
|
+
var buf;
|
|
84
|
+
var newlineIdx;
|
|
85
|
+
buf = concatU8A(self.chunks);
|
|
86
|
+
newlineIdx = 0;
|
|
87
|
+
while (-1 !== (newlineIdx = buf.indexOf(10))) {
|
|
88
|
+
var line;
|
|
89
|
+
line = self.decoder.decode(buf.subarray(0, newlineIdx));
|
|
90
|
+
buf = buf.subarray(newlineIdx + 1);
|
|
91
|
+
self.chunks = [buf];
|
|
92
|
+
if (self.debug) console.log(self.name, line);
|
|
93
|
+
var msg;
|
|
94
|
+
msg = JSON.parse(line);
|
|
95
|
+
if (!msg.id) {
|
|
96
|
+
console.log("message has no id, skipping", msg);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
var cb;
|
|
100
|
+
var iter;
|
|
101
|
+
cb = self.callbacks[msg.id];
|
|
102
|
+
iter = self.iterators[msg.id];
|
|
103
|
+
if (((cb || iter) && (((typeof msg !== 'undefined') && (typeof msg.result !== 'undefined')) || msg.error))) {
|
|
104
|
+
if ((cb && ((typeof msg !== 'undefined') && (typeof msg.result !== 'undefined')))) {
|
|
105
|
+
cb.resolve(msg.result);
|
|
106
|
+
} else if (iter && ((typeof msg !== 'undefined') && (typeof msg.result !== 'undefined'))) {
|
|
107
|
+
iter.result = {
|
|
108
|
+
value: msg.result
|
|
109
|
+
};
|
|
110
|
+
if (msg.done) {
|
|
111
|
+
iter.result.done = true;
|
|
112
|
+
delete self.iterators[msg.id];
|
|
113
|
+
}
|
|
114
|
+
} else if (cb && msg.error) {
|
|
115
|
+
var err;
|
|
116
|
+
err = new Error(msg.error.message);
|
|
117
|
+
err.stack = msg.error.stack;
|
|
118
|
+
cb.reject(err);
|
|
119
|
+
} else if (iter && msg.error) {
|
|
120
|
+
iter.err = new Error(msg.error.message);
|
|
121
|
+
iter.err.stack = msg.error.stack;
|
|
122
|
+
}
|
|
123
|
+
if (cb) delete self.callbacks[msg.id];
|
|
124
|
+
} else if (msg.method) {
|
|
125
|
+
if (!self.exports[msg.method]) {
|
|
126
|
+
self._error(msg.id, "method not found: " + msg.method);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
var m;
|
|
130
|
+
var r;
|
|
131
|
+
var chunk;
|
|
132
|
+
m = msg;
|
|
133
|
+
r = undefined;
|
|
134
|
+
chunk = {};
|
|
135
|
+
try {
|
|
136
|
+
r = await self.exports[m.method](msg.params, msg.stream);
|
|
137
|
+
if (((typeof r !== 'undefined') && !!r[Symbol.asyncIterator])) {
|
|
138
|
+
_res = [];
|
|
139
|
+
while (!chunk.done) {
|
|
140
|
+
chunk = await r.next();
|
|
141
|
+
if (chunk.err) throw chunk.err;
|
|
142
|
+
if (typeof(_ref = !!chunk.value ? self._result(m.id, chunk.value, chunk.done) : undefined) !== 'undefined') _res.push(_ref);
|
|
143
|
+
}
|
|
144
|
+
_ref0 = _res;
|
|
145
|
+
} else {
|
|
146
|
+
_ref0 = self._result(m.id, r, true);
|
|
147
|
+
}
|
|
148
|
+
_ref0;
|
|
149
|
+
} catch (e) {
|
|
150
|
+
self._error(m.id, e.message, e.stack);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return pump();
|
|
155
|
+
}
|
|
156
|
+
pump;
|
|
157
|
+
pump();
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
JSONRPC;
|
|
161
|
+
JSONRPC.prototype._write = (async function(payload) {
|
|
162
|
+
var encoder, data;
|
|
163
|
+
var encoder;
|
|
164
|
+
var data;
|
|
165
|
+
encoder = new TextEncoder();
|
|
166
|
+
data = encoder.encode(JSON.stringify(payload) + "\n");
|
|
167
|
+
return await this.writer.write(data);
|
|
168
|
+
});
|
|
169
|
+
JSONRPC.prototype._error = (function(msgId, message, stack) {
|
|
170
|
+
return this._write({
|
|
171
|
+
jsonrpc: "2.0",
|
|
172
|
+
id: msgId,
|
|
173
|
+
error: {
|
|
174
|
+
message: message,
|
|
175
|
+
stack: stack
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
JSONRPC.prototype._result = (function(msgId, result, done) {
|
|
180
|
+
return (function(self, payload) {
|
|
181
|
+
if (done) payload.done = true;
|
|
182
|
+
return self._write(payload);
|
|
183
|
+
})(this, {
|
|
184
|
+
jsonrpc: "2.0",
|
|
185
|
+
id: msgId,
|
|
186
|
+
result: ((typeof result !== 'undefined') ? result : null)
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
JSONRPC.prototype._call = (async function(method, params, stream) {
|
|
190
|
+
var self, msgId;
|
|
191
|
+
var self;
|
|
192
|
+
var msgId;
|
|
193
|
+
self = this;
|
|
194
|
+
msgId = self.msgId;
|
|
195
|
+
self.msgId++;
|
|
196
|
+
self._write({
|
|
197
|
+
jsonrpc: "2.0",
|
|
198
|
+
id: msgId,
|
|
199
|
+
method: method,
|
|
200
|
+
params: params,
|
|
201
|
+
stream: stream
|
|
202
|
+
});
|
|
203
|
+
if (!stream) return new Promise((function(resolve, reject) {
|
|
204
|
+
return (self.callbacks[msgId] = {
|
|
205
|
+
resolve: resolve,
|
|
206
|
+
reject: reject
|
|
207
|
+
});
|
|
208
|
+
}));
|
|
209
|
+
return (self.iterators[msgId] = new AsyncIter());
|
|
210
|
+
});
|
|
211
|
+
exports.jsonrpc = jsonrpc;
|
package/dist/tune.js
CHANGED
|
@@ -2099,12 +2099,12 @@ function text2run(text, ctx, opts) {
|
|
|
2099
2099
|
}
|
|
2100
2100
|
text2run;
|
|
2101
2101
|
async function file2run(args, params, ctx) {
|
|
2102
|
-
var lctx,
|
|
2102
|
+
var lctx, uext, node, text, res, longFormatRegex, response, _ref;
|
|
2103
2103
|
var lctx;
|
|
2104
2104
|
lctx = ctx.clone();
|
|
2105
2105
|
lctx.ms.unshift(envmd(params));
|
|
2106
|
-
var
|
|
2107
|
-
|
|
2106
|
+
var uext;
|
|
2107
|
+
uext = "";
|
|
2108
2108
|
if (args.filename) {
|
|
2109
2109
|
node = await ctx.resolve(args.filename);
|
|
2110
2110
|
if (node) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tune-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "tune - your everyday LLM toolkit.",
|
|
5
5
|
"main": "dist/tune.js",
|
|
6
6
|
"module": "dist/tune.mjs",
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"require": "./dist/tune.js",
|
|
11
11
|
"import": "./dist/tune.mjs"
|
|
12
|
+
},
|
|
13
|
+
"./fsctx": {
|
|
14
|
+
"require": "./dist/fsctx.js"
|
|
12
15
|
}
|
|
13
16
|
},
|
|
14
17
|
"keywords": [
|
package/tools/default.ctx.js
CHANGED
|
@@ -1,51 +1,20 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
3
|
|
|
4
|
-
const {
|
|
4
|
+
const { curFile, fsMix, defaultWrite } = require("../dist/fsctx.js");
|
|
5
|
+
const { file2run, makeContext } = require("../dist/tune.js");
|
|
5
6
|
|
|
6
7
|
async function makeSchema(params, ctx) {
|
|
7
|
-
return
|
|
8
|
+
return file2run({ filename: path.join(__dirname, "schema.tool.chat")}, params, ctx);
|
|
8
9
|
}
|
|
9
10
|
let dirs = [];
|
|
10
11
|
if (process.env.TUNE_PATH) {
|
|
11
12
|
dirs = process.env.TUNE_PATH.split(path.delimiter);
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
+
console.log(defaultWrite())
|
|
14
15
|
|
|
15
16
|
module.exports = [
|
|
16
|
-
|
|
17
|
-
if (!this.stack || !this.stack.length) {
|
|
18
|
-
return
|
|
19
|
-
}
|
|
20
|
-
const { filename } = this.stack[0];
|
|
21
|
-
let value
|
|
22
|
-
switch(name) {
|
|
23
|
-
case "__filename":
|
|
24
|
-
value = filename
|
|
25
|
-
break
|
|
26
|
-
case "__dirname":
|
|
27
|
-
value = path.dirname(filename)
|
|
28
|
-
break
|
|
29
|
-
case "__basename":
|
|
30
|
-
value = path.basename(filename)
|
|
31
|
-
break
|
|
32
|
-
case "__name":
|
|
33
|
-
value = path.parse(filename).name
|
|
34
|
-
break
|
|
35
|
-
case "__ext":
|
|
36
|
-
value = path.parse(filename).ext
|
|
37
|
-
break
|
|
38
|
-
default:
|
|
39
|
-
break
|
|
40
|
-
}
|
|
41
|
-
if (value) {
|
|
42
|
-
return {
|
|
43
|
-
type: "text",
|
|
44
|
-
read: async () => value
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return
|
|
48
|
-
},
|
|
17
|
+
curFile,
|
|
49
18
|
fsMix(dirs, { makeSchema }),
|
|
50
19
|
require("./openai.ctx.js"),
|
|
51
20
|
require("./openrouter.ctx.js"),
|
|
@@ -53,9 +22,5 @@ module.exports = [
|
|
|
53
22
|
require("./gemini.ctx.js"),
|
|
54
23
|
require("./mistral.ctx.js"),
|
|
55
24
|
require("./groq.ctx.js"),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
fs.mkdirSync(directory, { recursive: true });
|
|
59
|
-
fs.writeFileSync(filename, data)
|
|
60
|
-
}
|
|
61
|
-
];
|
|
25
|
+
defaultWrite()
|
|
26
|
+
]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Transcribe audio using Groq Whisper API",
|
|
3
|
+
"parameters": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"file": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"description": "Path to the audio file to transcribe"
|
|
9
|
+
},
|
|
10
|
+
"url": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "URL of the audio file to transcribe"
|
|
13
|
+
},
|
|
14
|
+
"model": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Model to use for transcription",
|
|
17
|
+
"default": "whisper-large-v3-turbo"
|
|
18
|
+
},
|
|
19
|
+
"language": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Language spoken in the audio"
|
|
22
|
+
},
|
|
23
|
+
"text": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Optional text prompt to guide transcription"
|
|
26
|
+
},
|
|
27
|
+
"response_format": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Format of the transcription response",
|
|
30
|
+
"enum": ["json", "verbose_json", "text"],
|
|
31
|
+
"default": "json"
|
|
32
|
+
},
|
|
33
|
+
"temperature": {
|
|
34
|
+
"type": "number",
|
|
35
|
+
"description": "Sampling temperature for transcription",
|
|
36
|
+
"default": 0
|
|
37
|
+
},
|
|
38
|
+
"timestamp_granularities": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"items": {
|
|
41
|
+
"type": "string"
|
|
42
|
+
},
|
|
43
|
+
"description": "Timestamp granularities to include if response_format is verbose_json",
|
|
44
|
+
"default": ["segment"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
export default async function groqWhisper({
|
|
4
|
+
file,
|
|
5
|
+
url,
|
|
6
|
+
model = "whisper-large-v3-turbo",
|
|
7
|
+
language,
|
|
8
|
+
text,
|
|
9
|
+
response_format = "json",
|
|
10
|
+
temperature = 0,
|
|
11
|
+
timestamp_granularities = ["segment"]
|
|
12
|
+
}, ctx) {
|
|
13
|
+
const key = await ctx.read("GROQ_KEY");
|
|
14
|
+
|
|
15
|
+
const formData = new FormData();
|
|
16
|
+
|
|
17
|
+
// Add file or url
|
|
18
|
+
if (file) {
|
|
19
|
+
if (!fs.existsSync(file)) {
|
|
20
|
+
return "file not found"
|
|
21
|
+
}
|
|
22
|
+
const fileBlob = await fs.openAsBlob(file);
|
|
23
|
+
formData.append('file', fileBlob, file);
|
|
24
|
+
} else if (url) {
|
|
25
|
+
formData.append('url', url);
|
|
26
|
+
} else {
|
|
27
|
+
throw new Error('Either file or url parameter is required');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Add required model
|
|
31
|
+
formData.append('model', model);
|
|
32
|
+
|
|
33
|
+
// Add optional parameters
|
|
34
|
+
if (language) formData.append('language', language);
|
|
35
|
+
if (text) formData.append('prompt', text);
|
|
36
|
+
if (response_format) formData.append('response_format', response_format);
|
|
37
|
+
if (temperature !== undefined) formData.append('temperature', temperature.toString());
|
|
38
|
+
if (timestamp_granularities && response_format === 'verbose_json') {
|
|
39
|
+
timestamp_granularities.forEach(granularity => {
|
|
40
|
+
formData.append('timestamp_granularities[]', granularity);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const response = await fetch("https://api.groq.com/openai/v1/audio/transcriptions", {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers: {
|
|
47
|
+
"Authorization": `Bearer ${key}`,
|
|
48
|
+
},
|
|
49
|
+
body: formData,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const errorText = await response.text();
|
|
54
|
+
throw new Error(`Error: ${response.status} ${response.statusText}\n${errorText}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const result = await response.json();
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Convert audio file to text using OpenAI's transcription API with advanced options",
|
|
3
|
+
"parameters": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"file": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"description": "Path or identifier of the audio file to transcribe"
|
|
9
|
+
},
|
|
10
|
+
"model": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Model to use for transcription",
|
|
13
|
+
"default": "gpt-4o-transcribe"
|
|
14
|
+
},
|
|
15
|
+
"language": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "Language spoken in the audio, optional"
|
|
18
|
+
},
|
|
19
|
+
"prompt": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Prompt to guide transcription, optional"
|
|
22
|
+
},
|
|
23
|
+
"response_format": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"enum": ["json", "verbose_json", "text"],
|
|
26
|
+
"description": "Format of the transcription response",
|
|
27
|
+
"default": "json"
|
|
28
|
+
},
|
|
29
|
+
"temperature": {
|
|
30
|
+
"type": "number",
|
|
31
|
+
"description": "Sampling temperature for transcription",
|
|
32
|
+
"default": 0
|
|
33
|
+
},
|
|
34
|
+
"timestamp_granularities": {
|
|
35
|
+
"type": "array",
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "string"
|
|
38
|
+
},
|
|
39
|
+
"description": "Timestamp granularities for detailed transcription, supported only for whisper-1 model with verbose_json response_format"
|
|
40
|
+
},
|
|
41
|
+
"stream": {
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"description": "Whether to return a streaming response",
|
|
44
|
+
"default": false
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": ["file"]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
|
|
3
|
+
export default async function openaiSTT({
|
|
4
|
+
file,
|
|
5
|
+
model = "gpt-4o-transcribe",
|
|
6
|
+
language,
|
|
7
|
+
prompt,
|
|
8
|
+
response_format = "json",
|
|
9
|
+
temperature = 0,
|
|
10
|
+
timestamp_granularities,
|
|
11
|
+
stream = false
|
|
12
|
+
}, ctx) {
|
|
13
|
+
const key = await ctx.read("OPENAI_KEY");
|
|
14
|
+
|
|
15
|
+
if (!file) {
|
|
16
|
+
throw new Error('File parameter is required');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const formData = new FormData();
|
|
20
|
+
|
|
21
|
+
// Add file
|
|
22
|
+
const fileBlob = await fs.openAsBlob(file);
|
|
23
|
+
formData.append('file', fileBlob, file);
|
|
24
|
+
|
|
25
|
+
// Add required model
|
|
26
|
+
formData.append('model', model);
|
|
27
|
+
|
|
28
|
+
// Add optional parameters
|
|
29
|
+
if (language) formData.append('language', language);
|
|
30
|
+
if (prompt) formData.append('prompt', prompt);
|
|
31
|
+
if (response_format) formData.append('response_format', response_format);
|
|
32
|
+
if (temperature !== undefined) formData.append('temperature', temperature.toString());
|
|
33
|
+
if (stream) formData.append('stream', stream.toString());
|
|
34
|
+
|
|
35
|
+
// Timestamp granularities (only supported for whisper-1 with verbose_json)
|
|
36
|
+
if (timestamp_granularities && model === 'whisper-1' && response_format === 'verbose_json') {
|
|
37
|
+
timestamp_granularities.forEach(granularity => {
|
|
38
|
+
formData.append('timestamp_granularities[]', granularity);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const response = await fetch("https://api.openai.com/v1/audio/transcriptions", {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: {
|
|
45
|
+
"Authorization": `Bearer ${key}`,
|
|
46
|
+
},
|
|
47
|
+
body: formData,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
const errorText = await response.text();
|
|
52
|
+
throw new Error(`Error: ${response.status} ${response.statusText}\n${errorText}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (stream) {
|
|
56
|
+
// For streaming responses, return the response stream
|
|
57
|
+
return response.body;
|
|
58
|
+
} else {
|
|
59
|
+
// For non-streaming responses, parse JSON or return text based on response_format
|
|
60
|
+
if (response_format === 'text') {
|
|
61
|
+
return await response.text();
|
|
62
|
+
} else {
|
|
63
|
+
return await response.json();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|