kbot
This commit is contained in:
parent
5c11bb5d06
commit
fae42d6c37
340
packages/osr-ai-tools/package-lock.json
generated
340
packages/osr-ai-tools/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@plastichub/osr-ai-tools",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@plastichub/osr-ai-tools",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.2",
|
||||
"dependencies": {
|
||||
"@plastichub/core": "^0.2.6",
|
||||
"@plastichub/fs": "^0.13.41",
|
||||
@ -16,12 +16,13 @@
|
||||
"axios": "^1.7.9",
|
||||
"cheerio": "^1.0.0",
|
||||
"find-up": "^5.0.0",
|
||||
"glob": "^11.0.1",
|
||||
"inquirer": "^12.2.0",
|
||||
"jsdom": "^25.0.1",
|
||||
"marked": "^15.0.4",
|
||||
"mime-types": "^2.1.35",
|
||||
"nodemailer": "^6.9.16",
|
||||
"openai": "^4.76.3",
|
||||
"openai": "^4.80.1",
|
||||
"p-map": "^4.0.0",
|
||||
"puppeteer": "^23.11.1",
|
||||
"screenshot-desktop": "^1.15.0",
|
||||
@ -41,11 +42,11 @@
|
||||
"devDependencies": {
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/marked": "^6.0.0",
|
||||
"@types/node": "^18.19.68",
|
||||
"@types/node": "^18.19.74",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/turndown": "^5.0.5",
|
||||
"@types/yargs": "^17.0.33",
|
||||
"ts-node": "^10.9.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
},
|
||||
@ -610,6 +611,87 @@
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/glob/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@plastichub/fs/node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@plastichub/osr-commons/-/osr-commons-0.5.3.tgz",
|
||||
@ -637,93 +719,6 @@
|
||||
"node": ">= 14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/glob": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
|
||||
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^4.0.1",
|
||||
"minimatch": "^10.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/jackspeak": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
|
||||
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/lru-cache": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/minimatch": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/path-scurry": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@plastichub/osr-commons/node_modules/typescript": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
|
||||
@ -898,9 +893,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.19.68",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.68.tgz",
|
||||
"integrity": "sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw==",
|
||||
"version": "18.19.74",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.74.tgz",
|
||||
"integrity": "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
@ -2422,21 +2417,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "10.4.5",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
|
||||
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"jackspeak": "^4.0.1",
|
||||
"minimatch": "^10.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
@ -2520,15 +2518,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
@ -2858,18 +2856,18 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
|
||||
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
@ -3047,10 +3045,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"license": "ISC"
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/mailsplit": {
|
||||
"version": "5.4.2",
|
||||
@ -3352,9 +3353,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "4.77.0",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.77.0.tgz",
|
||||
"integrity": "sha512-WWacavtns/7pCUkOWvQIjyOfcdr9X+9n9Vvb0zFeKVDAqwCMDHB+iSr24SVaBAhplvSG6JrRXFpcNM9gWhOGIw==",
|
||||
"version": "4.80.1",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.80.1.tgz",
|
||||
"integrity": "sha512-+6+bbXFwbIE88foZsBEt36bPkgZPdyFN82clAXG61gnHb2gXdZApDyRrcAHqEtpYICywpqaNo57kOm9dtnb7Cw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "^18.11.18",
|
||||
@ -3369,9 +3370,13 @@
|
||||
"openai": "bin/cli"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ws": "^8.18.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ws": {
|
||||
"optional": true
|
||||
},
|
||||
"zod": {
|
||||
"optional": true
|
||||
}
|
||||
@ -3617,16 +3622,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
@ -3937,93 +3942,6 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/glob": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz",
|
||||
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^4.0.1",
|
||||
"minimatch": "^10.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/jackspeak": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz",
|
||||
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/lru-cache": {
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/minimatch": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf/node_modules/path-scurry": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^11.0.0",
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/rotating-file-stream": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/rotating-file-stream/-/rotating-file-stream-3.2.5.tgz",
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
"marked": "^15.0.4",
|
||||
"mime-types": "^2.1.35",
|
||||
"nodemailer": "^6.9.16",
|
||||
"openai": "^4.76.3",
|
||||
"openai": "^4.80.1",
|
||||
"p-map": "^4.0.0",
|
||||
"puppeteer": "^23.11.1",
|
||||
"screenshot-desktop": "^1.15.0",
|
||||
|
||||
14
packages/osr-code-bot/.dockerignore
Normal file
14
packages/osr-code-bot/.dockerignore
Normal file
@ -0,0 +1,14 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
Dockefile
|
||||
.dockerignore
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
.env
|
||||
.env.*
|
||||
*.log
|
||||
coverage
|
||||
.kbot
|
||||
dist
|
||||
build
|
||||
@ -0,0 +1 @@
|
||||
{}
|
||||
37
packages/osr-code-bot/.gitignore
vendored
Normal file
37
packages/osr-code-bot/.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# Deno
|
||||
.deno
|
||||
deno.lock
|
||||
deno.json._decorators
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
# Build output
|
||||
build/
|
||||
out/
|
||||
|
||||
# Environment files
|
||||
.env*
|
||||
!src/.env/
|
||||
!src/.env/*md
|
||||
|
||||
# Generated files
|
||||
.dts
|
||||
types/
|
||||
.D_Store
|
||||
.vscode/!settings.json
|
||||
|
||||
# Logs
|
||||
*.Log
|
||||
*.Log.*
|
||||
docs
|
||||
docs-internal
|
||||
systems/code-server-defaults
|
||||
kbot-extensions
|
||||
systems/workspace/kbot-docs
|
||||
systems/.code-server/code-server-ipc.sock
|
||||
systems/.code-server/User/workspaceStorage/
|
||||
systems/code-server-defaults
|
||||
systems/.code-server
|
||||
|
||||
kbot-tests
|
||||
kbot-extensions
|
||||
49
packages/osr-code-bot/.npmignore
Normal file
49
packages/osr-code-bot/.npmignore
Normal file
@ -0,0 +1,49 @@
|
||||
# Ignore node_modules directory
|
||||
node_modules/
|
||||
|
||||
# Ignore log files
|
||||
*.log
|
||||
|
||||
# Ignore temporary files
|
||||
*.tmp
|
||||
|
||||
# Ignore coverage reports
|
||||
coverage/
|
||||
|
||||
.kbot
|
||||
docs
|
||||
docs_
|
||||
.env
|
||||
report
|
||||
.vscode
|
||||
config
|
||||
systems
|
||||
tools.json
|
||||
commit.json
|
||||
docker.sh
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
scripts
|
||||
todos.md
|
||||
tests
|
||||
tmp
|
||||
dist/node_modules
|
||||
dist/data
|
||||
dist/.kbot
|
||||
dist/package-lock.json
|
||||
|
||||
# Logs
|
||||
*.Log
|
||||
*.Log.*
|
||||
docs
|
||||
docs-internal
|
||||
systems/code-server-defaults
|
||||
kbot-extensions
|
||||
systems/workspace/kbot-docs
|
||||
systems/.code-server/code-server-ipc.sock
|
||||
systems/.code-server/User/workspaceStorage/
|
||||
systems/code-server-defaults
|
||||
systems/.code-server
|
||||
|
||||
kbot-tests
|
||||
kbot-extensions
|
||||
2
packages/osr-code-bot/.npmrc
Normal file
2
packages/osr-code-bot/.npmrc
Normal file
@ -0,0 +1,2 @@
|
||||
registry=https://registry.npmjs.org/
|
||||
save-exact=true
|
||||
51
packages/osr-code-bot/.travis.yml
Normal file
51
packages/osr-code-bot/.travis.yml
Normal file
@ -0,0 +1,51 @@
|
||||
# Travis CI Configuration
|
||||
language: node_js
|
||||
|
||||
# Specify the operating systems
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
- windows
|
||||
|
||||
# Specify the Node.js versions to test on
|
||||
node_js:
|
||||
- "node" # latest stable node
|
||||
|
||||
# Specific operating system and Node.js version combinations
|
||||
matrix:
|
||||
include:
|
||||
# Linux (Ubuntu)
|
||||
- os: linux
|
||||
dist: ubuntu-latest
|
||||
node_js: "node"
|
||||
|
||||
# macOS
|
||||
- os: osx
|
||||
node_js: "node"
|
||||
|
||||
# Windows
|
||||
- os: windows
|
||||
node_js: "node"
|
||||
|
||||
# Cache node_modules between builds
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
# Install dependencies
|
||||
install:
|
||||
- npm ci
|
||||
|
||||
# Run tests
|
||||
script:
|
||||
- npm test
|
||||
|
||||
# Before deployment scripts (optional)
|
||||
before_deploy:
|
||||
- npm run build
|
||||
|
||||
# Notifications
|
||||
notifications:
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
528
packages/osr-code-bot/.vscode/launch.json
vendored
Normal file
528
packages/osr-code-bot/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,528 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "create",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"create",
|
||||
"typescript",
|
||||
"-p=../ai-tests",
|
||||
"-n=test-simple",
|
||||
"--app='Command-1 : Distance by car, using Google, output the result at a given path. Create a file at src/constants.ts with the following content: export const GOOGLE_API_KEY'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"../ai-tests/test-simple",
|
||||
"--prompt='Add another command: create json schemas for functions in src/lib/*, using ts-json-schema-generator'",
|
||||
"--output='../ai-tests/test-simple-modified'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:git",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/tests/typescript",
|
||||
"args": [
|
||||
"init repository, using git tool",
|
||||
"--logLevel=1",
|
||||
"--router=openai",
|
||||
"--model=gpt-4o",
|
||||
"--disable='npm,terminal,user,interact,web,search'",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:templates:solidworks",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"../sw-test/",
|
||||
"--prompt='create for each *.cs file a dedicated documentation (with example code), eg: src_file.md, link them in readme.md'",
|
||||
"--template=./solidworks",
|
||||
"--include='*.md,*.cs'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:prompt:docker",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='./systems/prompt-docker.md'",
|
||||
"--template=typescript",
|
||||
"--disable=npm",
|
||||
"--include='systems/**'",
|
||||
"--dump='./test.sh'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:iterator",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='for each file in src/commands/*.ts, write a report in /reports/commands/file_name.md (skip existing reports using the file_exists tool), detected problems, possible solutions, and a conclusion, and example code'",
|
||||
//"--template=typescript",
|
||||
"--disable=npm,terminal",
|
||||
"--include='src/*.tsx,src/*.ts'",
|
||||
"--disable=terminal",
|
||||
"--dump='./test.sh'",
|
||||
"--include='src/*.ts'",
|
||||
"--disable=2",
|
||||
"--include=false"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:search:google",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='search google, osr-plastic extruders; write it as markdown in ./tests/search/google.md'",
|
||||
"--disable='npm,terminal'",
|
||||
"--include='./tests/search/google'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:search:serpapi",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='Find all post industrial plastic traders in Dresden Germany, using serpapi (map), write it to ./tests/search/yammi.md'",
|
||||
"--disable='npm,terminal'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:interact",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='use the interact tool to figure a person has psychopathic tendencies, ask at least 3 questions but not direct, store the result in prefs.json, as probabilty (merge), with reasons why; its for a llm study'",
|
||||
"--template=typescript",
|
||||
"--disable=npm",
|
||||
"--include='tests/*.json'",
|
||||
"--include='tests/*.md'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:web",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"./",
|
||||
"--prompt='summarize https://community.preciousplastic.com/u/farm-fab-lab-by-plat-institute using the web tool, store the result ( and all found links ) in ./tests/summarize/oa-tests.md'",
|
||||
"--disable=npm,terminal",
|
||||
"--include='tests/*.md'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "deepseek",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"summarize https://community.preciousplastic.com/u/farm-fab-lab-by-plat-institute using the web tool, store the result ( and all found links ) in ./tests/summarize/oa-tests.md",
|
||||
"--disable=npm,terminal,git,fs",
|
||||
"--router=deepseek",
|
||||
"--tools=fs"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:tools:email",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'send John the latest wheather report for Tarragona, as email'",
|
||||
"--disable='npm,terminal'",
|
||||
"--include='tests/*.md'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal", // <= the relevant part
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:tools:terminal:astro",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'create static site with Astro, using terminal tool'",
|
||||
"--disable='npm,git'",
|
||||
"--path=./tests/astro-test"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "types",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"types"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:tools:search",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'meaning of life, save to ./tests/search/meaning-of-life.md'",
|
||||
"--logLevel=1",
|
||||
"--include=src/commands/*.ts",
|
||||
"--include=src/zod_schema.ts",
|
||||
"--disable='npm,terminal,interact,git,search'",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "assistant:code",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'security audit for the given files, refer to code, and file names'",
|
||||
"--include=src/zod_schema.ts",
|
||||
"--disable='npm,terminal,interact,git,search'",
|
||||
"--mode=assistant",
|
||||
"--router=openai",
|
||||
"--model=gpt-4o",
|
||||
"--dst=./tests/assistant/code.md",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "assistant:pdf",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'total price(s) for all stainless parts (304), as markdown table, group by part prefixes'",
|
||||
"--include=./tests/assistant/invoice.pdf",
|
||||
"--disable='npm,terminal,interact,git,search'",
|
||||
"--mode=assistant",
|
||||
"--router=openai",
|
||||
"--model=gpt-4o",
|
||||
"--dst=./tests/assistant/invoice.md",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "assistant:md",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'identify all components (and brand), as markdown table, with location, with links, there are PIDs and a Controllino mini'",
|
||||
"--include2=./docs_/*.md",
|
||||
"--include=./tests/images/elzm-cab.jpg",
|
||||
"--disable='npm,terminal,interact,git,search'",
|
||||
"--router2=openai",
|
||||
"--model2=gpt-4o",
|
||||
"--mode=completion",
|
||||
"--dst=./tests/assistant/elzm.md",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:each:vars",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"summarize",
|
||||
"--logLevel=1",
|
||||
"--var-test=foo",
|
||||
"--dry",
|
||||
"--each=docs_/parameters.md",
|
||||
"--dst=./tests/each/${SRC_DIR}/${SRC_NAME}-${MODEL}-${ROUTER}.md",
|
||||
"--disable='npm,terminal,interact,git,search'",
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:tools:test",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"'dd a custom help function for yargs, write to src/help.ts, apply in src/main.ts'",
|
||||
"--logLevel=2",
|
||||
"--include2='tests/images-random/*.jpg'",
|
||||
"--include2='src/main.ts'",
|
||||
"--include2='src/zod_schema.ts'",
|
||||
"--include='tests/*.mp4'",
|
||||
"--include='tests/images/*.jpg'",
|
||||
"--include='C:\\Users\\zx\\Desktop\\osr\\tools-output.json'",
|
||||
"--include='C:\\Users\\zx\\Desktop\\osr\\osr-code-bot\\docs_\\docker.md'",
|
||||
"--include='D:\\Users\\mc007\\Desktop\\osr\\osr-search\\types2.js'",
|
||||
"--disable='npm,terminal,search,interact,git'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"console": "integratedTerminal", // <= the relevant part
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "modify:hono",
|
||||
"skipFiles": [],
|
||||
"program": "${workspaceFolder}\\main.js",
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/**/*.js"
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": [
|
||||
"modify",
|
||||
"--path='../sw-test'",
|
||||
"--prompt='take a screenshot (tool capture_screen), store the content as markdown in latest.md'"
|
||||
],
|
||||
"resolveSourceMapLocations": [
|
||||
"${workspaceFolder}/**",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"outputCapture": "std"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug Current Test File",
|
||||
"autoAttachChildProcesses": true,
|
||||
"skipFiles": [
|
||||
"<node_internals>/**",
|
||||
"**/node_modules/**"
|
||||
],
|
||||
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
|
||||
"args": [
|
||||
"run",
|
||||
"${relativeFile}"
|
||||
],
|
||||
"smartStep": true,
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
205
packages/osr-code-bot/README.md
Normal file
205
packages/osr-code-bot/README.md
Normal file
@ -0,0 +1,205 @@
|
||||
# @plastichub/code-bot
|
||||
|
||||
AI-powered command-line tool for code modifications and project management that supports multiple AI models and routers.
|
||||
|
||||
## Overview
|
||||
|
||||
Code-bot is a powerful CLI tool that helps developers automate code modifications, handle project management tasks, and integrate with various AI models for intelligent code and content assistance.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation Steps
|
||||
|
||||
KBot requires Node.js to run. It's recommended to use Node.js version 18 or higher.
|
||||
|
||||
1. Visit the official [Node.js website](https://nodejs.org/)
|
||||
2. Download the LTS (Long Term Support) version for your operating system
|
||||
3. Follow the installation wizard
|
||||
4. Verify installation by opening a terminal and running:
|
||||
```bash
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
### API Keys
|
||||
|
||||
KBot supports both OpenRouter and OpenAI APIs. You'll need at least one of these set up.
|
||||
|
||||
#### OpenRouter API (Recommended)
|
||||
|
||||
1. Visit [OpenRouter](https://openrouter.ai/)
|
||||
2. Sign up for an account
|
||||
3. Navigate to the API Keys section
|
||||
4. Create a new API key
|
||||
|
||||
#### OpenAI API (Optional)
|
||||
|
||||
1. Go to [OpenAI's platform](https://platform.openai.com/)
|
||||
2. Create an account or sign in
|
||||
3. Navigate to API keys section
|
||||
4. Create a new secret key
|
||||
|
||||
### Installation using Node NPM package manager
|
||||
|
||||
```bash
|
||||
npm install -g @plastichub/code-bot
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### API Keys Setup
|
||||
|
||||
Create configuration at `$HOME/.osr/.config.json` (or export OSR_CONFIG with path to config.json):
|
||||
|
||||
```json
|
||||
{
|
||||
"openrouter": {
|
||||
"key": "your-openrouter-key"
|
||||
},
|
||||
"openai": {
|
||||
"key": "your-openai-key"
|
||||
},
|
||||
"email": {
|
||||
"newsletter": {
|
||||
"host": "host.org",
|
||||
"port": 465,
|
||||
"debug": true,
|
||||
"transactionLog": true,
|
||||
"auth": {
|
||||
"user": "foo@bar.com",
|
||||
"pass": "pass"
|
||||
}
|
||||
}
|
||||
},
|
||||
"google": {
|
||||
"cse": "custom search engine id",
|
||||
"api_key": "google custom search api key"
|
||||
},
|
||||
"serpapi": {
|
||||
"key": "your SerpAPI key (optional, used for web searches(places, google maps))"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Preferences Setup
|
||||
|
||||
Optionally, create `.kbot/preferences.md` in your project directory to customize AI interactions:
|
||||
|
||||
```markdown
|
||||
## My Preferences
|
||||
|
||||
Gender : male
|
||||
Location : New York, USA (eg: `send me all saunas next to me`)
|
||||
Language : English
|
||||
Occupation : software developer, Typescript
|
||||
Age : 30+
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address : example@email.com (eg: `send me latest hacker news`)
|
||||
My wife's email address ("Anne") : example@email.com (eg: `send email to my wife, with latest local news')
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
- always Markdown
|
||||
- always add links
|
||||
- when sending emails, always add 'Best regards, [Your Name]'
|
||||
```
|
||||
# Command Line Parameters
|
||||
|
||||
This document describes all available command line parameters.
|
||||
|
||||
## Core Parameters
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `path` | Target directory | `.` | No |
|
||||
| `prompt` | The prompt. Supports file paths and environment variables | `./prompt.md` | No |
|
||||
| `output` | Optional output path for modified files (Tool mode only) | - | No |
|
||||
| `dst` | Optional destination path for the result, will substitute ${MODEL} and ${ROUTER} in the path. Used for "completion" mode | - | No |
|
||||
| `model` | AI model to use for processing | `anthropic/claude-3.5-sonnet` | No |
|
||||
| `router` | Router to use: openai or openrouter | `openrouter` | No |
|
||||
| `mode` | Chat completion mode: "completion" (without tools) or "tools" | `tools` | No |
|
||||
|
||||
## File Selection & Tools
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `include` | Glob patterns to match files for processing. Supports multiple patterns, e.g. `--include=src/*.tsx,src/*.ts --include=package.json` | - | No |
|
||||
| `disable` | Disable tools categories | `[]` | No |
|
||||
| `disableTools` | List of specific tools to disable | `[]` | No |
|
||||
|
||||
## Configuration & Profiles
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `profile` | Path to profile for variables. Supports environment variables | `${POLYMECH-ROOT}/profile.json` | No |
|
||||
| `env` | Environment (in profile) | `default` | No |
|
||||
| `config` | Path to JSON configuration file (API keys). Supports environment variables | - | No |
|
||||
| `preferences` | Path to preferences file (location, email, gender, etc). Supports environment variables | `./.kbot/preferences.md` | No |
|
||||
|
||||
## Debugging & Logging
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `logLevel` | Logging level for the application (0-4) | `2` | No |
|
||||
| `logs` | Logging directory | `./.kbot` | No |
|
||||
| `dump` | Create a script | - | No |
|
||||
| `dry` | Dry run - only write out parameters without making API calls | `false` | No |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Basic usage with default parameters
|
||||
kbot --prompt="What are the changes needed?"
|
||||
|
||||
# Specify model and router
|
||||
kbot --model="gpt-4" --router="openai" --prompt="Analyze this code"
|
||||
|
||||
# Process specific files
|
||||
kbot --include="src/*.ts" --include="package.json" --prompt="Check for security issues"
|
||||
|
||||
# Dry run with custom logging
|
||||
kbot --dry=true --logLevel=4 --prompt="Test run"
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Many path-based parameters support environment variables using the `${VARIABLE}` syntax:
|
||||
|
||||
- `${POLYMECH-ROOT}` - Root directory for Polymech
|
||||
- `${OSR-ROOT}` - Root directory for OSR
|
||||
|
||||
Example:
|
||||
```bash
|
||||
kbot --profile="${POLYMECH-ROOT}/custom-profile.json"
|
||||
```
|
||||
|
||||
# Working on Larger Directories
|
||||
|
||||
Since LLMs (Large Language Models) and providers are limited to very small 'context windows', it's necessary to feed them with smaller chunks instead. This document explains how to process larger directories efficiently.
|
||||
|
||||
## Directory Processing Example
|
||||
|
||||
Here's an example of how to walk through files and process them:
|
||||
|
||||
```bash
|
||||
osr-cli each --main='kbot \"read ${KEY} and translate to german, save in docs/language code/filename.md\" --include=\"${REL}\" --include=\".kbot/preferences.md\"' --list="./docs/*.md" --cwd=.
|
||||
```
|
||||
|
||||
### Parameter Explanation
|
||||
|
||||
- `each`: Command to process multiple files iteratively
|
||||
- `--main`: The main command (`kbot`) to execute for each file
|
||||
- `--include=\"${REL}\"` instructs kbot to include the current selected path
|
||||
- `--include=\".kbot/preferences.md\"` instructs kbot to include additional preferences about the task (eg: translation specifics)
|
||||
- `--list`: Specifies the file pattern to match
|
||||
- Supports include patterns (e.g., `"./docs/*.md"`)
|
||||
- `--cwd`: Sets the current working directory for the command execution. Default is the current directory (`.`)
|
||||
|
||||
**Note** requires `@plastichub/osr-cli-commons` to be installed globally:
|
||||
|
||||
```bash
|
||||
npm i -g @plastichub/osr-cli-commons
|
||||
```
|
||||
56
packages/osr-code-bot/client.js
Normal file
56
packages/osr-code-bot/client.js
Normal file
@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createClient = void 0;
|
||||
const openai_1 = require("openai");
|
||||
const index_1 = require("./index");
|
||||
const config_1 = require("./config");
|
||||
const createClient = (options) => {
|
||||
const config = (0, config_1.loadConfig)(options);
|
||||
let apiKey = options.api_key;
|
||||
if (!config) {
|
||||
index_1.logger.error("Config not found in $HOME/.osr/config.json. " +
|
||||
"Optionally, export OSR_CONFIG with the path to the configuration file, ");
|
||||
return undefined;
|
||||
}
|
||||
const router = options.router ?? "openrouter";
|
||||
let baseURL = options.baseURL;
|
||||
if (!options.baseURL) {
|
||||
switch (router) {
|
||||
case "openrouter":
|
||||
apiKey = apiKey || config?.openrouter?.key;
|
||||
if (!options.baseURL) {
|
||||
baseURL = "https://openrouter.ai/api/v1";
|
||||
}
|
||||
break;
|
||||
case "openai":
|
||||
apiKey = apiKey || config?.openai?.key;
|
||||
break;
|
||||
case "deepseek":
|
||||
apiKey = apiKey || config?.deepseek?.key;
|
||||
if (!options.baseURL) {
|
||||
baseURL = "https://api.deepseek.com";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!apiKey) {
|
||||
index_1.logger.error(`No ${router} key found. Please provide an "api_key", set it in the config, or pass it via JSON config.`);
|
||||
return undefined;
|
||||
}
|
||||
if (router === "openrouter" && !options.model) {
|
||||
options.model = "anthropic/claude-3.5-sonnet";
|
||||
}
|
||||
if (router === "openai" && !options.model) {
|
||||
options.model = "gpt-4o";
|
||||
}
|
||||
if (router === "deepseek" && !options.model) {
|
||||
options.model = "deepseek-chat";
|
||||
}
|
||||
index_1.logger.info(`Creating client with ${router} router, model ${options.model}, and API key ${apiKey} at ${baseURL}`);
|
||||
return new openai_1.OpenAI({
|
||||
apiKey,
|
||||
baseURL,
|
||||
});
|
||||
};
|
||||
exports.createClient = createClient;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBK0I7QUFDL0IsbUNBQWdDO0FBQ2hDLHFDQUFxQztBQUc5QixNQUFNLFlBQVksR0FBRyxDQUFDLE9BQXFCLEVBQUUsRUFBRTtJQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFBLG1CQUFVLEVBQUMsT0FBTyxDQUFDLENBQUE7SUFDbEMsSUFBSSxNQUFNLEdBQVcsT0FBTyxDQUFDLE9BQU8sQ0FBQTtJQUNwQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixjQUFNLENBQUMsS0FBSyxDQUNSLDhDQUE4QztZQUM5Qyx5RUFBeUUsQ0FDNUUsQ0FBQztRQUNGLE9BQU8sU0FBUyxDQUFBO0lBQ3BCLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLFlBQVksQ0FBQTtJQUM3QyxJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFBO0lBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbkIsUUFBUSxNQUFNLEVBQUUsQ0FBQztZQUNiLEtBQUssWUFBWTtnQkFDYixNQUFNLEdBQUcsTUFBTSxJQUFJLE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNuQixPQUFPLEdBQUcsOEJBQThCLENBQUE7Z0JBQzVDLENBQUM7Z0JBQ0QsTUFBTTtZQUNWLEtBQUssUUFBUTtnQkFDVCxNQUFNLEdBQUcsTUFBTSxJQUFJLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDO2dCQUN2QyxNQUFNO1lBQ1YsS0FBSyxVQUFVO2dCQUNYLE1BQU0sR0FBRyxNQUFNLElBQUksTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ25CLE9BQU8sR0FBRywwQkFBMEIsQ0FBQTtnQkFDeEMsQ0FBQztnQkFDRCxNQUFNO1FBQ2QsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixjQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sTUFBTSw0RkFBNEYsQ0FBQyxDQUFDO1FBQ3ZILE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLE1BQU0sS0FBSyxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDNUMsT0FBTyxDQUFDLEtBQUssR0FBRyw2QkFBNkIsQ0FBQTtJQUNqRCxDQUFDO0lBRUQsSUFBSSxNQUFNLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFBO0lBQzVCLENBQUM7SUFFRCxJQUFJLE1BQU0sS0FBSyxVQUFVLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUMsT0FBTyxDQUFDLEtBQUssR0FBRyxlQUFlLENBQUE7SUFDbkMsQ0FBQztJQUVELGNBQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLE1BQU0sa0JBQWtCLE9BQU8sQ0FBQyxLQUFLLGlCQUFpQixNQUFNLE9BQU8sT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUNqSCxPQUFPLElBQUksZUFBTSxDQUFDO1FBQ2QsTUFBTTtRQUNOLE9BQU87S0FDVixDQUFDLENBQUE7QUFDTixDQUFDLENBQUE7QUF0RFksUUFBQSxZQUFZLGdCQXNEeEIifQ==
|
||||
77
packages/osr-code-bot/collector.js
Normal file
77
packages/osr-code-bot/collector.js
Normal file
@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.collector = void 0;
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const osr_log_1 = require("@plastichub/osr-log");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const _1 = require("./");
|
||||
const collector = (options, client) => {
|
||||
return {
|
||||
//OpenAI
|
||||
onMessage: (message) => {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'openai-message.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onMessage', logFile);
|
||||
logger.info(message);
|
||||
},
|
||||
onToolCall: async (message) => {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'tool-call.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onToolCall', logFile);
|
||||
try {
|
||||
const msg = { ...message, arguments: JSON.parse(message.arguments) };
|
||||
logger.debug(msg);
|
||||
}
|
||||
catch (e) {
|
||||
logger.debug(message);
|
||||
}
|
||||
},
|
||||
onFunctionCallResult: (message) => {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'tool-call-result.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onFunctionCallResult', logFile);
|
||||
try {
|
||||
const msg = { message: JSON.parse(message) };
|
||||
logger.debug(msg);
|
||||
}
|
||||
catch (e) {
|
||||
logger.debug(message);
|
||||
}
|
||||
},
|
||||
onChatCompletion: (message) => {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'completion.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onChatCompletion', logFile);
|
||||
logger.debug(message);
|
||||
},
|
||||
onContent: (content) => {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'content.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onContent', logFile);
|
||||
logger.debug(content);
|
||||
},
|
||||
onTool(category, name, args, result) {
|
||||
const logFile = path_1.default.resolve(path_1.default.join((0, osr_commons_1.resolve)(options.logs), 'tool.json'));
|
||||
const logger = (0, osr_log_1.winstonLogger)('collector:onTool', logFile);
|
||||
logger.debug({ category, name, args, result });
|
||||
},
|
||||
onToolBefore: async (ctx, args) => {
|
||||
try {
|
||||
_1.logger.debug(`onToolBefore :${ctx.name}`);
|
||||
}
|
||||
catch (e) {
|
||||
_1.logger.error(e);
|
||||
}
|
||||
return args;
|
||||
},
|
||||
onToolAfter: async (ctx, args, result) => {
|
||||
try {
|
||||
_1.logger.debug(`onToolAfter : ${ctx.name}`);
|
||||
}
|
||||
catch (e) {
|
||||
_1.logger.error(e);
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
};
|
||||
};
|
||||
exports.collector = collector;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NvbGxlY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxnREFBdUI7QUFLdkIsaURBQW9EO0FBQ3BELHlEQUFpRDtBQUlqRCx5QkFBMkM7QUFHcEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFxQixFQUFFLE1BQWMsRUFBYyxFQUFFO0lBQzNFLE9BQU87UUFDSCxRQUFRO1FBQ1IsU0FBUyxFQUFFLENBQUMsT0FBbUMsRUFBRSxFQUFFO1lBQy9DLE1BQU0sT0FBTyxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFBLHFCQUFPLEVBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLHFCQUFxQixDQUFDLENBQUMsQ0FBQTtZQUNyRixNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFhLEVBQUMscUJBQXFCLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDNUQsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN4QixDQUFDO1FBQ0QsVUFBVSxFQUFFLEtBQUssRUFBRSxPQUEyQyxFQUFFLEVBQUU7WUFDOUQsTUFBTSxPQUFPLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUEscUJBQU8sRUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFBO1lBQ2hGLE1BQU0sTUFBTSxHQUFHLElBQUEsdUJBQWEsRUFBQyxzQkFBc0IsRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUM3RCxJQUFJLENBQUM7Z0JBQ0QsTUFBTSxHQUFHLEdBQUcsRUFBRSxHQUFHLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQTtnQkFDcEUsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNyQixDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3pCLENBQUM7UUFDTCxDQUFDO1FBQ0Qsb0JBQW9CLEVBQUUsQ0FBQyxPQUFlLEVBQUUsRUFBRTtZQUN0QyxNQUFNLE9BQU8sR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBQSxxQkFBTyxFQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDLENBQUE7WUFDdkYsTUFBTSxNQUFNLEdBQUcsSUFBQSx1QkFBYSxFQUFDLGdDQUFnQyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQ3ZFLElBQUksQ0FBQztnQkFDRCxNQUFNLEdBQUcsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUE7Z0JBQzVDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDckIsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUN6QixDQUFDO1FBQ0wsQ0FBQztRQUNELGdCQUFnQixFQUFFLENBQUMsT0FBdUIsRUFBRSxFQUFFO1lBQzFDLE1BQU0sT0FBTyxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFBLHFCQUFPLEVBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQTtZQUNqRixNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFhLEVBQUMsNEJBQTRCLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDbkUsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN6QixDQUFDO1FBQ0QsU0FBUyxFQUFFLENBQUMsT0FBZSxFQUFFLEVBQUU7WUFDM0IsTUFBTSxPQUFPLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUEscUJBQU8sRUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQTtZQUM5RSxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFhLEVBQUMscUJBQXFCLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDNUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN6QixDQUFDO1FBQ0QsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU07WUFDL0IsTUFBTSxPQUFPLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUEscUJBQU8sRUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQTtZQUMzRSxNQUFNLE1BQU0sR0FBRyxJQUFBLHVCQUFhLEVBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDekQsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7UUFDbEQsQ0FBQztRQUNELFlBQVksRUFBRSxLQUFLLEVBQUUsR0FBbUMsRUFBRSxJQUFTLEVBQUUsRUFBRTtZQUNuRSxJQUFHLENBQUM7Z0JBQ0EsU0FBWSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7WUFDbkQsQ0FBQztZQUFBLE9BQU0sQ0FBQyxFQUFDLENBQUM7Z0JBQ04sU0FBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN6QixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUE7UUFDZixDQUFDO1FBQ0QsV0FBVyxFQUFFLEtBQUssRUFBRSxHQUFtQyxFQUFFLElBQVMsRUFBRSxNQUFZLEVBQUUsRUFBRTtZQUNoRixJQUFJLENBQUM7Z0JBQ0QsU0FBWSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7WUFDbkQsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsU0FBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN6QixDQUFDO1lBQ0QsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDcEIsQ0FBQztLQUNKLENBQUE7QUFDTCxDQUFDLENBQUE7QUE1RFksUUFBQSxTQUFTLGFBNERyQiJ9
|
||||
43
packages/osr-code-bot/commands/build.js
Normal file
43
packages/osr-code-bot/commands/build.js
Normal file
@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.build = void 0;
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const __1 = require("../");
|
||||
const openai_1 = require("../models/openai");
|
||||
const openrouter_1 = require("../models/openrouter");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const build = async () => {
|
||||
const examplesSrc = path_1.default.resolve(__dirname, '../docs_/examples.md');
|
||||
if ((0, exists_1.sync)(examplesSrc)) {
|
||||
const examples = (0, read_1.sync)(examplesSrc, 'string') || '';
|
||||
const examplesPath = path_1.default.resolve(__dirname, '../src/docs-internal/examples.ts');
|
||||
(0, write_1.sync)(examplesPath, `export const examples = ${JSON.stringify(examples)}`);
|
||||
__1.logger.info(`Examples file generated " ${examplesPath}`);
|
||||
}
|
||||
else {
|
||||
__1.logger.error(`Examples file not found ${examplesSrc}`);
|
||||
}
|
||||
const config = (0, osr_commons_1.CONFIG_DEFAULT)();
|
||||
const modelsOpenAI = await (0, openai_1.fetchOpenAIModels)(config.openai.key);
|
||||
const modelsOpenRouter = (await (0, openrouter_1.fetchOpenRouterModels)()).map((model) => {
|
||||
return {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
pricing: model.pricing,
|
||||
context: model.context,
|
||||
created: model.created
|
||||
};
|
||||
});
|
||||
const modelsOpenAIPath = path_1.default.resolve(__dirname, '../src/models/cache/openai.ts');
|
||||
(0, write_1.sync)(modelsOpenAIPath, `export const models = ${JSON.stringify(modelsOpenAI)}`);
|
||||
const modelsOpenRouterPath = path_1.default.resolve(__dirname, '../src/models/cache/openrouter.ts');
|
||||
(0, write_1.sync)(modelsOpenRouterPath, `export const models = ${JSON.stringify(modelsOpenRouter)}`);
|
||||
};
|
||||
exports.build = build;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvYnVpbGQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0RBQXVCO0FBRXZCLDhDQUFrRDtBQUNsRCxnREFBb0Q7QUFDcEQsa0RBQXNEO0FBQ3RELDJCQUE0QjtBQUM1Qiw2Q0FBb0Q7QUFDcEQscURBQTZFO0FBQzdFLHlEQUF3RDtBQUdqRCxNQUFNLEtBQUssR0FBRyxLQUFLLElBQUksRUFBRTtJQUM5QixNQUFNLFdBQVcsR0FBSSxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxzQkFBc0IsQ0FBQyxDQUFBO0lBQ3BFLElBQUcsSUFBQSxhQUFNLEVBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLFFBQVEsR0FBRyxJQUFBLFdBQUksRUFBQyxXQUFXLEVBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ2pELE1BQU0sWUFBWSxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGtDQUFrQyxDQUFDLENBQUE7UUFDaEYsSUFBQSxZQUFLLEVBQUMsWUFBWSxFQUFDLDJCQUEyQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQTtRQUN6RSxVQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixZQUFZLEVBQUUsQ0FBQyxDQUFBO0lBQzFELENBQUM7U0FBSSxDQUFDO1FBQ0osVUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsV0FBVyxFQUFFLENBQUMsQ0FBQTtJQUN4RCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsSUFBQSw0QkFBYyxHQUFTLENBQUE7SUFFdEMsTUFBTSxZQUFZLEdBQUksTUFBTSxJQUFBLDBCQUFpQixFQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDaEUsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLE1BQU0sSUFBQSxrQ0FBcUIsR0FBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDckUsT0FBTztZQUNMLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUNaLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtZQUNoQixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDdEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztTQUN2QixDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7SUFDRixNQUFNLGdCQUFnQixHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLCtCQUErQixDQUFDLENBQUE7SUFDakYsSUFBQSxZQUFLLEVBQUMsZ0JBQWdCLEVBQUMseUJBQXlCLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRS9FLE1BQU0sb0JBQW9CLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsbUNBQW1DLENBQUMsQ0FBQTtJQUN6RixJQUFBLFlBQUssRUFBQyxvQkFBb0IsRUFBQyx5QkFBeUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUN6RixDQUFDLENBQUE7QUE1QlksUUFBQSxLQUFLLFNBNEJqQiJ9
|
||||
14
packages/osr-code-bot/commands/examples.js
Normal file
14
packages/osr-code-bot/commands/examples.js
Normal file
@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.examples = void 0;
|
||||
const marked_1 = require("marked");
|
||||
const marked_terminal_1 = require("marked-terminal");
|
||||
const examples_1 = require("../docs-internal/examples");
|
||||
const examples = () => {
|
||||
marked_1.marked.use((0, marked_terminal_1.markedTerminal)({
|
||||
emoji: false,
|
||||
}));
|
||||
process.stdout.write((0, marked_1.marked)(examples_1.examples));
|
||||
};
|
||||
exports.examples = examples;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhhbXBsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvZXhhbXBsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQStCO0FBQy9CLHFEQUFnRDtBQUNoRCx3REFBK0Q7QUFFeEQsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO0lBQzNCLGVBQU0sQ0FBQyxHQUFHLENBQUMsSUFBQSxnQ0FBYyxFQUN2QjtRQUNFLEtBQUssRUFBRSxLQUFLO0tBQ2IsQ0FDRixDQUFDLENBQUE7SUFDRixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFBLGVBQU0sRUFBQyxtQkFBTyxDQUFXLENBQUMsQ0FBQTtBQUNqRCxDQUFDLENBQUE7QUFQWSxRQUFBLFFBQVEsWUFPcEIifQ==
|
||||
40
packages/osr-code-bot/commands/fetch.js
Normal file
40
packages/osr-code-bot/commands/fetch.js
Normal file
@ -0,0 +1,40 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetch = void 0;
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
const __1 = require("..");
|
||||
const openai_1 = require("../models/openai");
|
||||
const openrouter_1 = require("../models/openrouter");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const fetch = async () => {
|
||||
const config = (0, osr_commons_1.CONFIG_DEFAULT)();
|
||||
if (config.openai && config.openai.key) {
|
||||
const modelsOpenAI = await (0, openai_1.fetchOpenAIModels)(config.openai.key);
|
||||
if (modelsOpenAI) {
|
||||
const modelsOpenAIPath = path_1.default.resolve((0, __1.module_root)(), 'openai.json');
|
||||
(0, write_1.sync)(modelsOpenAIPath, modelsOpenAI);
|
||||
__1.logger.info(`Fetched ${modelsOpenAI.length} OpenAI models, to ${modelsOpenAIPath}`);
|
||||
}
|
||||
else {
|
||||
__1.logger.error(`Failed to fetch OpenAI models`);
|
||||
}
|
||||
}
|
||||
const modelsOpenRouter = (await (0, openrouter_1.fetchOpenRouterModels)()).map((model) => {
|
||||
return {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
pricing: model.pricing,
|
||||
context: model.context,
|
||||
created: model.created
|
||||
};
|
||||
});
|
||||
const modelsOpenRouterPath = path_1.default.resolve((0, __1.module_root)(), 'openrouter.json');
|
||||
(0, write_1.sync)(modelsOpenRouterPath, modelsOpenRouter);
|
||||
__1.logger.info(`Fetched ${modelsOpenRouter.length} OpenRouter models, to ${modelsOpenRouterPath}`);
|
||||
};
|
||||
exports.fetch = fetch;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmV0Y2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvZmV0Y2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0RBQXVCO0FBQ3ZCLGdEQUFvRDtBQUNwRCwwQkFBd0M7QUFDeEMsNkNBQW9EO0FBQ3BELHFEQUE0RDtBQUM1RCx5REFBd0Q7QUFFakQsTUFBTSxLQUFLLEdBQUcsS0FBSyxJQUFJLEVBQUU7SUFFOUIsTUFBTSxNQUFNLEdBQUcsSUFBQSw0QkFBYyxHQUFTLENBQUE7SUFDdEMsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkMsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFBLDBCQUFpQixFQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDL0QsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixNQUFNLGdCQUFnQixHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsSUFBQSxlQUFXLEdBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQTtZQUNuRSxJQUFBLFlBQUssRUFBQyxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsQ0FBQTtZQUNyQyxVQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsWUFBWSxDQUFDLE1BQU0sc0JBQXNCLGdCQUFnQixFQUFFLENBQUMsQ0FBQTtRQUNyRixDQUFDO2FBQU0sQ0FBQztZQUNOLFVBQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQTtRQUMvQyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUFNLElBQUEsa0NBQXFCLEdBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQ3JFLE9BQU87WUFDTCxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7WUFDWixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7WUFDaEIsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTztZQUN0QixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87U0FDdkIsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0lBQ0YsTUFBTSxvQkFBb0IsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsZUFBVyxHQUFFLEVBQUUsaUJBQWlCLENBQUMsQ0FBQTtJQUMzRSxJQUFBLFlBQUssRUFBQyxvQkFBb0IsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO0lBQzdDLFVBQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxnQkFBZ0IsQ0FBQyxNQUFNLDBCQUEwQixvQkFBb0IsRUFBRSxDQUFDLENBQUE7QUFDakcsQ0FBQyxDQUFBO0FBMUJZLFFBQUEsS0FBSyxTQTBCakIifQ==
|
||||
262
packages/osr-code-bot/commands/handlers/audio-handler.js
Normal file
262
packages/osr-code-bot/commands/handlers/audio-handler.js
Normal file
File diff suppressed because one or more lines are too long
7
packages/osr-code-bot/commands/handlers/base-handler.js
Normal file
7
packages/osr-code-bot/commands/handlers/base-handler.js
Normal file
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BaseHandler = void 0;
|
||||
class BaseHandler {
|
||||
}
|
||||
exports.BaseHandler = BaseHandler;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2hhbmRsZXJzL2Jhc2UtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLQSxNQUFzQixXQUFXO0NBR2hDO0FBSEQsa0NBR0MifQ==
|
||||
163
packages/osr-code-bot/commands/handlers/image-handler.js
Normal file
163
packages/osr-code-bot/commands/handlers/image-handler.js
Normal file
File diff suppressed because one or more lines are too long
70
packages/osr-code-bot/commands/handlers/index.js
Normal file
70
packages/osr-code-bot/commands/handlers/index.js
Normal file
@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createHandlers = createHandlers;
|
||||
exports.detectAndHandle = detectAndHandle;
|
||||
const text_handler_1 = require("./text-handler");
|
||||
const audio_handler_1 = require("./audio-handler");
|
||||
const image_handler_1 = require("./image-handler");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const path = __importStar(require("path"));
|
||||
function createHandlers(options) {
|
||||
return [
|
||||
new audio_handler_1.AudioHandler(options),
|
||||
new image_handler_1.ImageHandler(options),
|
||||
new text_handler_1.TextHandler(),
|
||||
];
|
||||
}
|
||||
async function detectAndHandle(content, options) {
|
||||
const handlers = createHandlers(options);
|
||||
// Check if content is a file path
|
||||
const contentStr = content.toString();
|
||||
if ((0, exists_1.sync)(contentStr)) {
|
||||
const filePath = path.resolve(contentStr);
|
||||
for (const handler of handlers) {
|
||||
if (await handler.canHandle(filePath, true)) {
|
||||
return handler.handle(filePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle as raw content
|
||||
for (const handler of handlers) {
|
||||
if (await handler.canHandle(content, false)) {
|
||||
return handler.handle(content, false);
|
||||
}
|
||||
}
|
||||
throw new Error('No suitable handler found for the input content');
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvaGFuZGxlcnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSx3Q0FNQztBQUVELDBDQXFCQztBQXBDRCxpREFBNEM7QUFDNUMsbURBQThDO0FBQzlDLG1EQUE4QztBQUM5QyxrREFBc0Q7QUFDdEQsMkNBQTRCO0FBRzVCLFNBQWdCLGNBQWMsQ0FBQyxPQUFxQjtJQUNsRCxPQUFPO1FBQ0wsSUFBSSw0QkFBWSxDQUFDLE9BQU8sQ0FBQztRQUN6QixJQUFJLDRCQUFZLENBQUMsT0FBTyxDQUFDO1FBQ3pCLElBQUksMEJBQVcsRUFBRTtLQUNsQixDQUFBO0FBQ0gsQ0FBQztBQUVNLEtBQUssVUFBVSxlQUFlLENBQUMsT0FBd0IsRUFBRSxPQUFxQjtJQUNuRixNQUFNLFFBQVEsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDeEMsa0NBQWtDO0lBQ2xDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUN0QyxJQUFJLElBQUEsYUFBTSxFQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDdkIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUMxQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQy9CLElBQUksTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ3hDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELHdCQUF3QjtJQUN4QixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQy9CLElBQUksTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDeEMsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7QUFDckUsQ0FBQyJ9
|
||||
68
packages/osr-code-bot/commands/handlers/text-handler.js
Normal file
68
packages/osr-code-bot/commands/handlers/text-handler.js
Normal file
@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TextHandler = void 0;
|
||||
const base_handler_1 = require("./base-handler");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const path = __importStar(require("path"));
|
||||
class TextHandler extends base_handler_1.BaseHandler {
|
||||
async canHandle(content, isPath) {
|
||||
if (isPath) {
|
||||
// For file paths, check file extension
|
||||
const ext = path.extname(content).toLowerCase();
|
||||
return ['.txt', '.md', '.json', '.js', '.ts'].includes(ext);
|
||||
}
|
||||
// For raw content, try to decode as UTF-8 text
|
||||
try {
|
||||
if (Buffer.isBuffer(content)) {
|
||||
content.toString('utf8');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async handle(content, isPath) {
|
||||
if (isPath) {
|
||||
// Read content from file
|
||||
return (0, read_1.sync)(content, 'string');
|
||||
}
|
||||
// Return raw content as string
|
||||
return Buffer.isBuffer(content) ? content.toString('utf8') : content;
|
||||
}
|
||||
}
|
||||
exports.TextHandler = TextHandler;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2hhbmRsZXJzL3RleHQtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxpREFBNkM7QUFDN0MsOENBQW1EO0FBQ25ELDJDQUE2QjtBQUU3QixNQUFhLFdBQVksU0FBUSwwQkFBVztJQUMxQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQXdCLEVBQUUsTUFBZTtRQUN2RCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsdUNBQXVDO1lBQ3ZDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBaUIsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzFELE9BQU8sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFFRCwrQ0FBK0M7UUFDL0MsSUFBSSxDQUFDO1lBQ0gsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQzdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQXdCLEVBQUUsTUFBZTtRQUNwRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gseUJBQXlCO1lBQ3pCLE9BQU8sSUFBQSxXQUFJLEVBQUMsT0FBaUIsRUFBRSxRQUFRLENBQVcsQ0FBQztRQUNyRCxDQUFDO1FBRUQsK0JBQStCO1FBQy9CLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3ZFLENBQUM7Q0FDRjtBQTVCRCxrQ0E0QkMifQ==
|
||||
52
packages/osr-code-bot/commands/help.js
Normal file
52
packages/osr-code-bot/commands/help.js
Normal file
@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.help = void 0;
|
||||
const marked_1 = require("marked");
|
||||
const marked_terminal_1 = require("marked-terminal");
|
||||
const zod_schema_1 = require("../zod_schema");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const zod_1 = require("zod");
|
||||
const help = () => {
|
||||
const schema = (0, zod_schema_1.OptionsSchema)();
|
||||
const desc = schema._def.description;
|
||||
const shape = schema.shape;
|
||||
const md = [
|
||||
'# KBot Command Line Interface',
|
||||
'',
|
||||
'```bash',
|
||||
'kplus modify [prompt] [options]',
|
||||
'```',
|
||||
'',
|
||||
'## Description',
|
||||
'',
|
||||
desc || 'KBot CLI Tool',
|
||||
'',
|
||||
'## Options',
|
||||
''
|
||||
];
|
||||
// Process each parameter
|
||||
for (const [key, def] of Object.entries(shape)) {
|
||||
const isOptional = def instanceof zod_1.z.ZodOptional;
|
||||
const defaultValue = (0, osr_commons_1.getDefaultValue)(def);
|
||||
const description = (0, osr_commons_1.getDescription)(def);
|
||||
md.push(`--${key}`);
|
||||
md.push('');
|
||||
md.push(`Description: ${description}`);
|
||||
if (defaultValue !== undefined) {
|
||||
md.push(`Default: \`${JSON.stringify(defaultValue)}\``);
|
||||
}
|
||||
md.push(`Required: ${(!isOptional).toString()}`);
|
||||
md.push('');
|
||||
}
|
||||
marked_1.marked.use((0, marked_terminal_1.markedTerminal)({
|
||||
emoji: false
|
||||
}));
|
||||
const content = (0, marked_1.marked)(md.join('\n'));
|
||||
process.stdout.write(content);
|
||||
return content;
|
||||
};
|
||||
exports.help = help;
|
||||
exports.default = async (argv) => {
|
||||
return (0, exports.help)();
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9oZWxwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUErQjtBQUMvQixxREFBZ0Q7QUFFaEQsOENBQTZDO0FBQzdDLHlEQUF5RTtBQUN6RSw2QkFBdUI7QUFFaEIsTUFBTSxJQUFJLEdBQUcsR0FBRyxFQUFFO0lBQ3ZCLE1BQU0sTUFBTSxHQUFHLElBQUEsMEJBQWEsR0FBRSxDQUFBO0lBQzlCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFBO0lBQ3BDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUE7SUFFMUIsTUFBTSxFQUFFLEdBQUc7UUFDVCwrQkFBK0I7UUFDL0IsRUFBRTtRQUNGLFNBQVM7UUFDVCxpQ0FBaUM7UUFDakMsS0FBSztRQUNMLEVBQUU7UUFDRixnQkFBZ0I7UUFDaEIsRUFBRTtRQUNGLElBQUksSUFBSSxlQUFlO1FBQ3ZCLEVBQUU7UUFDRixZQUFZO1FBQ1osRUFBRTtLQUNILENBQUE7SUFFRCx5QkFBeUI7SUFDekIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxHQUFHLFlBQVksT0FBQyxDQUFDLFdBQVcsQ0FBQTtRQUUvQyxNQUFNLFlBQVksR0FBRyxJQUFBLDZCQUFlLEVBQUMsR0FBRyxDQUFDLENBQUE7UUFDekMsTUFBTSxXQUFXLEdBQUcsSUFBQSw0QkFBYyxFQUFDLEdBQUcsQ0FBQyxDQUFBO1FBRXZDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFBO1FBQ25CLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDWCxFQUFFLENBQUMsSUFBSSxDQUFDLGdCQUFnQixXQUFXLEVBQUUsQ0FBQyxDQUFBO1FBQ3RDLElBQUksWUFBWSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN6RCxDQUFDO1FBQ0QsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDaEQsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNiLENBQUM7SUFFRCxlQUFNLENBQUMsR0FBRyxDQUFDLElBQUEsZ0NBQWMsRUFBQztRQUN4QixLQUFLLEVBQUUsS0FBSztLQUNiLENBQUMsQ0FBQyxDQUFBO0lBQ0gsTUFBTSxPQUFPLEdBQVcsSUFBQSxlQUFNLEVBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBVyxDQUFDO0lBQ3hELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzdCLE9BQU8sT0FBTyxDQUFBO0FBQ2hCLENBQUMsQ0FBQTtBQTNDWSxRQUFBLElBQUksUUEyQ2hCO0FBRUQsa0JBQWUsS0FBSyxFQUFFLElBQVMsRUFBRSxFQUFFO0lBQ2pDLE9BQU8sSUFBQSxZQUFJLEdBQUUsQ0FBQTtBQUNmLENBQUMsQ0FBQSJ9
|
||||
142
packages/osr-code-bot/commands/init.js
Normal file
142
packages/osr-code-bot/commands/init.js
Normal file
@ -0,0 +1,142 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.init = void 0;
|
||||
const dir_1 = require("@plastichub/fs/dir");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
const path = __importStar(require("path"));
|
||||
const tslog_1 = require("tslog");
|
||||
const constants_1 = require("../constants");
|
||||
const PREFERENCES_TEMPLATE = `# Personal Preferences
|
||||
|
||||
This file stores personal information and preferences to help the AI assistant provide more personalized and contextual responses.
|
||||
|
||||
## My Preferences
|
||||
|
||||
Gender :
|
||||
Location :
|
||||
Language :
|
||||
Occupation :
|
||||
Age :
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address :
|
||||
My wife's email address :
|
||||
My second wife's email address :
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
|
||||
- always Markdown
|
||||
- always add links to sources
|
||||
- when searching for news, always add links to videos
|
||||
`;
|
||||
const CONFIG_TEMPLATE = {
|
||||
"deepl": {
|
||||
"auth_key": "YOUR_DEEPL_AUTH_KEY",
|
||||
"free_api": false
|
||||
},
|
||||
"scaleserp": {
|
||||
"key": "YOUR_SCALE_SERP_KEY"
|
||||
},
|
||||
"geocoder": {
|
||||
"key": "YOUR_GEOCODER_KEY"
|
||||
},
|
||||
"serpapi": {
|
||||
"key": "YOUR_SERPAPI_KEY"
|
||||
},
|
||||
"openai": {
|
||||
"key": "YOUR_OPENAI_KEY"
|
||||
},
|
||||
"bigdata": {
|
||||
"key": "YOUR_BIGDATA_KEY"
|
||||
},
|
||||
"novita": {
|
||||
"key": "YOUR_NOVITA_KEY"
|
||||
},
|
||||
"perplexity": {
|
||||
"key": "YOUR_PERPLEXITY_KEY"
|
||||
},
|
||||
"gemini": {
|
||||
"key": "YOUR_GEMINI_KEY"
|
||||
},
|
||||
"openrouter": {
|
||||
"key": "YOUR_OPENROUTER_KEY"
|
||||
},
|
||||
"deepseek": {
|
||||
"key": "YOUR_DEEPSEEK_KEY"
|
||||
},
|
||||
"google": {
|
||||
"cse": "YOUR_GOOGLE_CSE",
|
||||
"api_key": "YOUR_GOOGLE_API_KEY"
|
||||
}
|
||||
};
|
||||
const init = async (argv) => {
|
||||
const logger = new tslog_1.Logger({
|
||||
hideLogPositionForProduction: true,
|
||||
maskPlaceholder: '***',
|
||||
name: constants_1.MODULE_NAME,
|
||||
prettyLogTemplate: "{{logLevelName}}\t[{{filePathWithLine}}{{name}}]\t",
|
||||
});
|
||||
const kbotDir = path.resolve(path.join(process.cwd(), `.${constants_1.MODULE_NAME}`));
|
||||
if (!(0, exists_1.sync)(kbotDir)) {
|
||||
(0, dir_1.sync)(kbotDir);
|
||||
}
|
||||
// Create preferences file if it doesn't exist
|
||||
const preferencesPath = path.resolve(kbotDir, 'preferences.md');
|
||||
if (!(0, exists_1.sync)(preferencesPath)) {
|
||||
(0, write_1.sync)(preferencesPath, PREFERENCES_TEMPLATE);
|
||||
logger.info(`📋 Created preferences file: ${preferencesPath}`);
|
||||
}
|
||||
else {
|
||||
logger.info(`📋 Preferences file already exists: ${preferencesPath}`);
|
||||
}
|
||||
// Create config file if it doesn't exist
|
||||
const configPath = path.resolve(kbotDir, 'config.json');
|
||||
if (!(0, exists_1.sync)(configPath)) {
|
||||
(0, write_1.sync)(configPath, CONFIG_TEMPLATE);
|
||||
logger.info(`📋 Created configuration file: ${configPath}`);
|
||||
}
|
||||
else {
|
||||
logger.info(`📋 Configuration file already exists: ${configPath}`);
|
||||
}
|
||||
logger.info('📋 Initialization complete!');
|
||||
return 0;
|
||||
};
|
||||
exports.init = init;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9pbml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUFnRDtBQUNoRCxrREFBc0Q7QUFDdEQsZ0RBQW9EO0FBQ3BELDJDQUE0QjtBQUU1QixpQ0FBK0I7QUFDL0IsNENBQTBDO0FBRTFDLE1BQU0sb0JBQW9CLEdBQUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F5QjVCLENBQUE7QUFFRCxNQUFNLGVBQWUsR0FBRztJQUN0QixPQUFPLEVBQUU7UUFDUCxVQUFVLEVBQUUscUJBQXFCO1FBQ2pDLFVBQVUsRUFBRSxLQUFLO0tBQ2xCO0lBQ0QsV0FBVyxFQUFFO1FBQ1gsS0FBSyxFQUFFLHFCQUFxQjtLQUM3QjtJQUNELFVBQVUsRUFBRTtRQUNWLEtBQUssRUFBRSxtQkFBbUI7S0FDM0I7SUFDRCxTQUFTLEVBQUU7UUFDVCxLQUFLLEVBQUUsa0JBQWtCO0tBQzFCO0lBQ0QsUUFBUSxFQUFFO1FBQ1IsS0FBSyxFQUFFLGlCQUFpQjtLQUN6QjtJQUNELFNBQVMsRUFBRTtRQUNULEtBQUssRUFBRSxrQkFBa0I7S0FDMUI7SUFDRCxRQUFRLEVBQUU7UUFDUixLQUFLLEVBQUUsaUJBQWlCO0tBQ3pCO0lBQ0QsWUFBWSxFQUFFO1FBQ1osS0FBSyxFQUFFLHFCQUFxQjtLQUM3QjtJQUNELFFBQVEsRUFBRTtRQUNSLEtBQUssRUFBRSxpQkFBaUI7S0FDekI7SUFDRCxZQUFZLEVBQUU7UUFDWixLQUFLLEVBQUUscUJBQXFCO0tBQzdCO0lBQ0QsVUFBVSxFQUFFO1FBQ1YsS0FBSyxFQUFFLG1CQUFtQjtLQUMzQjtJQUNELFFBQVEsRUFBRTtRQUNSLEtBQUssRUFBRSxpQkFBaUI7UUFDeEIsU0FBUyxFQUFFLHFCQUFxQjtLQUNqQztDQUNGLENBQUE7QUFFTSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsSUFBZSxFQUFFLEVBQUU7SUFDNUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxjQUFNLENBQVU7UUFDakMsNEJBQTRCLEVBQUUsSUFBSTtRQUNsQyxlQUFlLEVBQUUsS0FBSztRQUN0QixJQUFJLEVBQUUsdUJBQVc7UUFDakIsaUJBQWlCLEVBQUUsb0RBQW9EO0tBQ3hFLENBQUMsQ0FBQTtJQUNGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSx1QkFBVyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3pFLElBQUksQ0FBQyxJQUFBLGFBQU0sRUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3JCLElBQUEsVUFBRyxFQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2QsQ0FBQztJQUNELDhDQUE4QztJQUM5QyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO0lBQy9ELElBQUksQ0FBQyxJQUFBLGFBQU0sRUFBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1FBQzdCLElBQUEsWUFBSyxFQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFBO1FBQzVDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLGVBQWUsRUFBRSxDQUFDLENBQUE7SUFDaEUsQ0FBQztTQUFJLENBQUM7UUFDSixNQUFNLENBQUMsSUFBSSxDQUFDLHVDQUF1QyxlQUFlLEVBQUUsQ0FBQyxDQUFBO0lBQ3ZFLENBQUM7SUFFRCx5Q0FBeUM7SUFDekMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUE7SUFDdkQsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDeEIsSUFBQSxZQUFLLEVBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFBO1FBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLFVBQVUsRUFBRSxDQUFDLENBQUE7SUFDN0QsQ0FBQztTQUFJLENBQUM7UUFDSixNQUFNLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxVQUFVLEVBQUUsQ0FBQyxDQUFBO0lBQ3BFLENBQUM7SUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7SUFDMUMsT0FBTyxDQUFDLENBQUE7QUFDVixDQUFDLENBQUE7QUE5QlksUUFBQSxJQUFJLFFBOEJoQiJ9
|
||||
212
packages/osr-code-bot/commands/run-assistant.js
Normal file
212
packages/osr-code-bot/commands/run-assistant.js
Normal file
@ -0,0 +1,212 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runAssistant = exports.createOpenAIFile = void 0;
|
||||
const path = __importStar(require("path"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const __1 = require("../");
|
||||
const run_completion_1 = require("./run-completion");
|
||||
const source_1 = require("../source");
|
||||
const prompt_1 = require("../prompt");
|
||||
const console_1 = require("console");
|
||||
const supported = {
|
||||
".c": "text/x-c",
|
||||
".cpp": "text/x-c++",
|
||||
".cs": "text/x-csharp",
|
||||
".css": "text/css",
|
||||
".doc": "application/msword",
|
||||
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
".go": "text/x-golang",
|
||||
".html": "text/html",
|
||||
".java": "text/x-java",
|
||||
".js": "text/javascript",
|
||||
".json": "application/json",
|
||||
".md": "text/markdown",
|
||||
".pdf": "application/pdf",
|
||||
".php": "text/x-php",
|
||||
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
".py": "text/x-python", // sometimes text/x-script.python
|
||||
".rb": "text/x-ruby",
|
||||
".sh": "application/x-sh",
|
||||
".tex": "text/x-tex",
|
||||
".ts": "application/typescript",
|
||||
".txt": "text/plain"
|
||||
};
|
||||
const createOpenAIFile = async (client, filePath, purpose = 'assistants') => {
|
||||
return client.files.create({
|
||||
file: fs.createReadStream(filePath),
|
||||
purpose: purpose
|
||||
});
|
||||
};
|
||||
exports.createOpenAIFile = createOpenAIFile;
|
||||
/*
|
||||
class EventHandler extends EventEmitter {
|
||||
constructor(client) {
|
||||
super();
|
||||
// this.client = client;
|
||||
}
|
||||
|
||||
async onEvent(event) {
|
||||
try {
|
||||
console.log(event);
|
||||
// Retrieve events that are denoted with 'requires_action'
|
||||
// since these will have our tool_calls
|
||||
if (event.event === "thread.run.requires_action") {
|
||||
await this.handleRequiresAction(
|
||||
event.data,
|
||||
event.data.id,
|
||||
event.data.thread_id,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error handling event:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async handleRequiresAction(data, runId, threadId) {
|
||||
try {
|
||||
const toolOutputs =
|
||||
data.required_action.submit_tool_outputs.tool_calls.map((toolCall) => {
|
||||
if (toolCall.function.name === "getCurrentTemperature") {
|
||||
return {
|
||||
tool_call_id: toolCall.id,
|
||||
output: "57",
|
||||
};
|
||||
} else if (toolCall.function.name === "getRainProbability") {
|
||||
return {
|
||||
tool_call_id: toolCall.id,
|
||||
output: "0.06",
|
||||
};
|
||||
}
|
||||
});
|
||||
// Submit all the tool outputs at the same time
|
||||
await this.submitToolOutputs(toolOutputs, runId, threadId);
|
||||
} catch (error) {
|
||||
console.error("Error processing required action:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async submitToolOutputs(toolOutputs, runId, threadId) {
|
||||
try {
|
||||
// Use the submitToolOutputsStream helper
|
||||
const stream = this.client.beta.threads.runs.submitToolOutputsStream(
|
||||
threadId,
|
||||
runId,
|
||||
{ tool_outputs: toolOutputs },
|
||||
);
|
||||
for await (const event of stream) {
|
||||
this.emit("event", event);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error submitting tool outputs:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
const runAssistant = async (client, params, options) => {
|
||||
const sessionId = Date.now().toString();
|
||||
const sessionMessages = {
|
||||
sessionId,
|
||||
prompt: options.prompt,
|
||||
timestamp: new Date().toISOString(),
|
||||
messages: []
|
||||
};
|
||||
if (options.dry) {
|
||||
__1.logger.info('Dry run - skipping API call');
|
||||
return {
|
||||
result: 'DRY RUN',
|
||||
sessionMessages,
|
||||
result_raw: {},
|
||||
toolCalls: []
|
||||
};
|
||||
}
|
||||
const logMessage = (message, sessionId, prompt) => {
|
||||
return {
|
||||
...message,
|
||||
timestamp: new Date().toISOString(),
|
||||
sessionId,
|
||||
prompt
|
||||
};
|
||||
};
|
||||
let result = null;
|
||||
const prompt_ = await (0, prompt_1.prompt)(options);
|
||||
const assistant = await client.beta.assistants.create({
|
||||
name: "Documents Assistant",
|
||||
model: params.model,
|
||||
tools: [{ type: "file_search" }, ...params.tools],
|
||||
});
|
||||
let files = (0, source_1.glob)(path.resolve(options.path), options.include) || [];
|
||||
files = files.filter((f) => path.extname(f) in supported);
|
||||
const attachments = await Promise.all(files.map(async (file) => {
|
||||
const file_id = await (0, exports.createOpenAIFile)(client, file);
|
||||
return {
|
||||
file_id: file_id.id,
|
||||
tools: [{ type: "file_search" }]
|
||||
};
|
||||
}));
|
||||
const thread = await client.beta.threads.create({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: prompt_.content,
|
||||
attachments: attachments,
|
||||
}
|
||||
],
|
||||
});
|
||||
let defer;
|
||||
try {
|
||||
defer = new Promise((resolve, reject) => {
|
||||
const stream = client.beta.threads.runs
|
||||
.stream(thread.id, {
|
||||
assistant_id: assistant.id,
|
||||
})
|
||||
//.on("textCreated", (args) => logger.trace("assistant >",args))
|
||||
.on("toolCallCreated", (event) => __1.logger.debug("Assistant : " + event.type))
|
||||
.on("messageDone", async (event) => {
|
||||
if (event.content[0].type === "text") {
|
||||
resolve(event.content[0]);
|
||||
}
|
||||
});
|
||||
return stream;
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
__1.logger.error(`Failed to run assistant: ${e.message}`, console_1.error);
|
||||
}
|
||||
const ret = await defer;
|
||||
return await (0, run_completion_1.onCompletion)(ret.text.value, options);
|
||||
};
|
||||
exports.runAssistant = runAssistant;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWFzc2lzdGFudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9ydW4tYXNzaXN0YW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE0QjtBQUM1Qix1Q0FBd0I7QUFHeEIsMkJBQTRCO0FBQzVCLHFEQUErQztBQUMvQyxzQ0FBZ0M7QUFDaEMsc0NBQWtDO0FBQ2xDLHFDQUErQjtBQUUvQixNQUFNLFNBQVMsR0FBMkI7SUFDeEMsSUFBSSxFQUFFLFVBQVU7SUFDaEIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsS0FBSyxFQUFFLGVBQWU7SUFDdEIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsTUFBTSxFQUFFLG9CQUFvQjtJQUM1QixPQUFPLEVBQUUseUVBQXlFO0lBQ2xGLEtBQUssRUFBRSxlQUFlO0lBQ3RCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLE9BQU8sRUFBRSxhQUFhO0lBQ3RCLEtBQUssRUFBRSxpQkFBaUI7SUFDeEIsT0FBTyxFQUFFLGtCQUFrQjtJQUMzQixLQUFLLEVBQUUsZUFBZTtJQUN0QixNQUFNLEVBQUUsaUJBQWlCO0lBQ3pCLE1BQU0sRUFBRSxZQUFZO0lBQ3BCLE9BQU8sRUFBRSwyRUFBMkU7SUFDcEYsS0FBSyxFQUFFLGVBQWUsRUFBVSxpQ0FBaUM7SUFDakUsS0FBSyxFQUFFLGFBQWE7SUFDcEIsS0FBSyxFQUFFLGtCQUFrQjtJQUN6QixNQUFNLEVBQUUsWUFBWTtJQUNwQixLQUFLLEVBQUUsd0JBQXdCO0lBQy9CLE1BQU0sRUFBRSxZQUFZO0NBQ3JCLENBQUM7QUFFSyxNQUFNLGdCQUFnQixHQUFHLEtBQUssRUFBRSxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxVQUFrQixZQUFZLEVBQUUsRUFBRTtJQUN6RyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ3pCLElBQUksRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDO1FBQ25DLE9BQU8sRUFBRSxPQUFjO0tBQ3hCLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQUxZLFFBQUEsZ0JBQWdCLG9CQUs1QjtBQUNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUErREU7QUFHSyxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLE1BQVcsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDcEYsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBQ3ZDLE1BQU0sZUFBZSxHQUFHO1FBQ3RCLFNBQVM7UUFDVCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1FBQ25DLFFBQVEsRUFBRSxFQUFFO0tBQ2IsQ0FBQTtJQUVELElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLFVBQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtRQUMxQyxPQUFPO1lBQ0wsTUFBTSxFQUFFLFNBQVM7WUFDakIsZUFBZTtZQUNmLFVBQVUsRUFBRSxFQUFFO1lBQ2QsU0FBUyxFQUFFLEVBQUU7U0FDZCxDQUFBO0lBQ0gsQ0FBQztJQUNELE1BQU0sVUFBVSxHQUFHLENBQUMsT0FBWSxFQUFFLFNBQWlCLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDN0QsT0FBTztZQUNMLEdBQUcsT0FBTztZQUNWLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNuQyxTQUFTO1lBQ1QsTUFBTTtTQUNQLENBQUE7SUFDSCxDQUFDLENBQUE7SUFFRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUE7SUFFakIsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLGVBQU0sRUFBQyxPQUFPLENBQUMsQ0FBQTtJQUNyQyxNQUFNLFNBQVMsR0FBRyxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUNwRCxJQUFJLEVBQUUscUJBQXFCO1FBQzNCLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSztRQUNuQixLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7S0FFbEQsQ0FBQyxDQUFBO0lBRUYsSUFBSSxLQUFLLEdBQUcsSUFBQSxhQUFJLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUNuRSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQTtJQUV6RCxNQUFNLFdBQVcsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBWSxFQUFFLEVBQUU7UUFDckUsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHdCQUFnQixFQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUNwRCxPQUFPO1lBQ0wsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFFO1lBQ25CLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxDQUFDO1NBQ2pDLENBQUE7SUFDSCxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBR0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDOUMsUUFBUSxFQUFFO1lBQ1I7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO2dCQUN4QixXQUFXLEVBQUUsV0FBa0I7YUFDaEM7U0FDRjtLQUNGLENBQUMsQ0FBQTtJQUVGLElBQUksS0FBSyxDQUFBO0lBQ1QsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3RDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUk7aUJBQ3BDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO2dCQUNqQixZQUFZLEVBQUUsU0FBUyxDQUFDLEVBQUU7YUFDM0IsQ0FBQztnQkFDRixnRUFBZ0U7aUJBQy9ELEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsVUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUMzRSxFQUFFLENBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDakMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztvQkFDckMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFDM0IsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFBO1lBQ0osT0FBTyxNQUFNLENBQUE7UUFDZixDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsVUFBTSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLGVBQUssQ0FBQyxDQUFBO0lBQzlELENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQTtJQUN2QixPQUFPLE1BQU0sSUFBQSw2QkFBWSxFQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ3BELENBQUMsQ0FBQTtBQWhGWSxRQUFBLFlBQVksZ0JBZ0Z4QiJ9
|
||||
81
packages/osr-code-bot/commands/run-completion.js
Normal file
81
packages/osr-code-bot/commands/run-completion.js
Normal file
@ -0,0 +1,81 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runCompletion = exports.onCompletion = void 0;
|
||||
const marked_1 = require("marked");
|
||||
const marked_terminal_1 = require("marked-terminal");
|
||||
const path = __importStar(require("path"));
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const __1 = require("../");
|
||||
const script_1 = require("../utils/script");
|
||||
const filters_1 = require("../filters");
|
||||
const onCompletion = async (result = "", options) => {
|
||||
result = (0, filters_1.applyFilters)(result, options.filters || []);
|
||||
if (options.dst) {
|
||||
const dstPath = path.resolve((0, osr_commons_1.resolve)(options.dst, false, {
|
||||
...options.variables,
|
||||
MODEL: path.parse(options.model).name,
|
||||
ROUTER: options.router,
|
||||
}));
|
||||
(0, write_1.sync)(dstPath, result);
|
||||
__1.logger.debug(`Wrote completion result to ${dstPath}`);
|
||||
}
|
||||
else {
|
||||
marked_1.marked.use((0, marked_terminal_1.markedTerminal)({
|
||||
emoji: false,
|
||||
}));
|
||||
const content = (0, marked_1.marked)(result);
|
||||
process.stdout.write(content);
|
||||
}
|
||||
(0, script_1.dumpAsScript)(options);
|
||||
return result;
|
||||
};
|
||||
exports.onCompletion = onCompletion;
|
||||
const runCompletion = async (client, params, options) => {
|
||||
if (options.dry) {
|
||||
__1.logger.info('Dry run - skipping API call');
|
||||
return false;
|
||||
}
|
||||
const completion = await client.chat.completions.create({
|
||||
model: options.model,
|
||||
messages: params.messages,
|
||||
});
|
||||
const result = completion.choices[0].message.content;
|
||||
(0, exports.onCompletion)(result, options);
|
||||
return result;
|
||||
};
|
||||
exports.runCompletion = runCompletion;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLWNvbXBsZXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvcnVuLWNvbXBsZXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsbUNBQStCO0FBQy9CLHFEQUFnRDtBQUNoRCwyQ0FBNEI7QUFDNUIsZ0RBQW9EO0FBQ3BELHlEQUFpRDtBQUNqRCwyQkFBNEI7QUFDNUIsNENBQThDO0FBQzlDLHdDQUFpRDtBQUUxQyxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsU0FBYyxFQUFFLEVBQUUsT0FBa0IsRUFBRSxFQUFFO0lBQ3pFLE1BQU0sR0FBRyxJQUFBLHNCQUFZLEVBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxPQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQ2hFLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBQSxxQkFBTyxFQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFO1lBQ3ZELEdBQUcsT0FBTyxDQUFDLFNBQVM7WUFDcEIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUk7WUFDckMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3ZCLENBQUMsQ0FBQyxDQUFBO1FBQ0gsSUFBQSxZQUFLLEVBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3RCLFVBQU0sQ0FBQyxLQUFLLENBQUMsOEJBQThCLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDdkQsQ0FBQztTQUFNLENBQUM7UUFDTixlQUFNLENBQUMsR0FBRyxDQUFDLElBQUEsZ0NBQWMsRUFBQztZQUN4QixLQUFLLEVBQUUsS0FBSztTQUNiLENBQUMsQ0FBQyxDQUFBO1FBQ0gsTUFBTSxPQUFPLEdBQVcsSUFBQSxlQUFNLEVBQUMsTUFBTSxDQUFXLENBQUM7UUFDakQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDL0IsQ0FBQztJQUNELElBQUEscUJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQTtJQUNyQixPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQW5CWSxRQUFBLFlBQVksZ0JBbUJ4QjtBQUVNLE1BQU0sYUFBYSxHQUFHLEtBQUssRUFBRSxNQUFjLEVBQUUsTUFBVyxFQUFFLE9BQWtCLEVBQUUsRUFBRTtJQUNyRixJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNoQixVQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUE7UUFDMUMsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUM7UUFDdEQsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1FBQ3BCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtLQUMxQixDQUFDLENBQUE7SUFDRixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUE7SUFDcEQsSUFBQSxvQkFBWSxFQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUM3QixPQUFPLE1BQU0sQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQVpZLFFBQUEsYUFBYSxpQkFZekIifQ==
|
||||
66
packages/osr-code-bot/commands/run-tools.js
Normal file
66
packages/osr-code-bot/commands/run-tools.js
Normal file
@ -0,0 +1,66 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runTools = void 0;
|
||||
const content_1 = require("../utils/content");
|
||||
const __1 = require("../");
|
||||
const run_completion_1 = require("./run-completion");
|
||||
const runTools = async (client, params, options) => {
|
||||
const sessionId = Date.now().toString();
|
||||
const sessionMessages = {
|
||||
sessionId,
|
||||
prompt: options.prompt,
|
||||
timestamp: new Date().toISOString(),
|
||||
messages: []
|
||||
};
|
||||
if (options.dry) {
|
||||
__1.logger.info('Dry run - skipping API call');
|
||||
return {
|
||||
result: 'DRY RUN',
|
||||
sessionMessages,
|
||||
result_raw: {},
|
||||
toolCalls: []
|
||||
};
|
||||
}
|
||||
const logMessage = (message, sessionId, prompt) => {
|
||||
return {
|
||||
...message,
|
||||
timestamp: new Date().toISOString(),
|
||||
sessionId,
|
||||
prompt
|
||||
};
|
||||
};
|
||||
let runner = null;
|
||||
try {
|
||||
runner = await client.beta.chat.completions.runTools(params)
|
||||
.on('message', (message) => {
|
||||
options.collector.onMessage(logMessage(message, sessionId, options.prompt));
|
||||
})
|
||||
.on('functionCall', (tool) => {
|
||||
return options.collector.onToolCall(logMessage(tool, sessionId, options.prompt));
|
||||
})
|
||||
.on('functionCallResult', (a) => {
|
||||
options.collector.onFunctionCallResult(a);
|
||||
})
|
||||
.on('chatCompletion', options.collector.onChatCompletion)
|
||||
.on('content', options.collector.onContent);
|
||||
}
|
||||
catch (e) {
|
||||
__1.logger.trace(e);
|
||||
}
|
||||
let result = (0, content_1.content)(runner);
|
||||
try {
|
||||
result = await runner.finalChatCompletion();
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message.includes("(reading 'map')")) {
|
||||
__1.logger.error('Failed to complete runner: credits :)', error.message, error.message, error);
|
||||
return;
|
||||
}
|
||||
__1.logger.error('Failed to complete runner:', error.message, error.issues);
|
||||
return;
|
||||
}
|
||||
const ret = (0, content_1.content)(result);
|
||||
return await (0, run_completion_1.onCompletion)(ret, options);
|
||||
};
|
||||
exports.runTools = runTools;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmRzL3J1bi10b29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFJQSw4Q0FBMEM7QUFDMUMsMkJBQTRCO0FBQzVCLHFEQUErQztBQUV4QyxNQUFNLFFBQVEsR0FBRyxLQUFLLEVBQUUsTUFBYyxFQUFFLE1BQVcsRUFBRSxPQUFrQixFQUFFLEVBQUU7SUFDaEYsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBQ3ZDLE1BQU0sZUFBZSxHQUFHO1FBQ3RCLFNBQVM7UUFDVCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1FBQ25DLFFBQVEsRUFBRSxFQUFFO0tBQ2IsQ0FBQTtJQUNELElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLFVBQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtRQUMxQyxPQUFPO1lBQ0wsTUFBTSxFQUFFLFNBQVM7WUFDakIsZUFBZTtZQUNmLFVBQVUsRUFBRSxFQUFFO1lBQ2QsU0FBUyxFQUFFLEVBQUU7U0FDZCxDQUFBO0lBQ0gsQ0FBQztJQUNELE1BQU0sVUFBVSxHQUFHLENBQUMsT0FBWSxFQUFFLFNBQWlCLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDN0QsT0FBTztZQUNMLEdBQUcsT0FBTztZQUNWLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNuQyxTQUFTO1lBQ1QsTUFBTTtTQUNQLENBQUE7SUFDSCxDQUFDLENBQUE7SUFDRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUE7SUFDakIsSUFBSSxDQUFDO1FBQ0gsTUFBTSxHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUE2QyxDQUFDO2FBQ2hHLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFtQyxFQUFFLEVBQUU7WUFDckQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDN0UsQ0FBQyxDQUFDO2FBQ0QsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDLElBQXdDLEVBQUUsRUFBRTtZQUMvRCxPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBQ2xGLENBQUMsQ0FBQzthQUNELEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQzlCLE9BQU8sQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDM0MsQ0FBQyxDQUFDO2FBQ0QsRUFBRSxDQUFDLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUM7YUFDeEQsRUFBRSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQy9DLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsVUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqQixDQUFDO0lBRUQsSUFBSSxNQUFNLEdBQUcsSUFBQSxpQkFBTyxFQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQzVCLElBQUksQ0FBQztRQUNILE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO0lBQzdDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDOUMsVUFBTSxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUE7WUFDMUYsT0FBTTtRQUNSLENBQUM7UUFDRCxVQUFNLENBQUMsS0FBSyxDQUFDLDRCQUE0QixFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3ZFLE9BQU07SUFDUixDQUFDO0lBRUQsTUFBTSxHQUFHLEdBQUcsSUFBQSxpQkFBTyxFQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQzNCLE9BQU8sTUFBTSxJQUFBLDZCQUFZLEVBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ3pDLENBQUMsQ0FBQTtBQXpEWSxRQUFBLFFBQVEsWUF5RHBCIn0=
|
||||
149
packages/osr-code-bot/commands/run.js
Normal file
149
packages/osr-code-bot/commands/run.js
Normal file
File diff suppressed because one or more lines are too long
65
packages/osr-code-bot/config.js
Normal file
65
packages/osr-code-bot/config.js
Normal file
@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.loadConfig = void 0;
|
||||
const path = __importStar(require("path"));
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const index_1 = require("./index");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const env_1 = require("./utils/env");
|
||||
const loadConfig = (options) => {
|
||||
if (options.config) {
|
||||
try {
|
||||
const configPath = path.resolve((0, osr_commons_1.resolve)(options.config, false, (0, env_1.env_vars)()));
|
||||
if ((0, exists_1.sync)(configPath)) {
|
||||
const parsedConfig = (0, read_1.sync)(configPath, 'json');
|
||||
return parsedConfig;
|
||||
}
|
||||
else {
|
||||
index_1.logger.error(`Config file not found: ${configPath}`);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error(`Failed to parse config JSON: ${error.message}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const config = (0, osr_commons_1.CONFIG_DEFAULT)();
|
||||
return config;
|
||||
}
|
||||
};
|
||||
exports.loadConfig = loadConfig;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSwyQ0FBNEI7QUFDNUIseURBQWlFO0FBQ2pFLG1DQUFpQztBQUNqQyxrREFBc0Q7QUFDdEQsOENBQWtEO0FBRWxELHFDQUFzQztBQUMvQixNQUFNLFVBQVUsR0FBRyxDQUFDLE9BQXFCLEVBQUUsRUFBRTtJQUNoRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUM7WUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEscUJBQU8sRUFBQyxPQUFPLENBQUMsTUFBTSxFQUFDLEtBQUssRUFBQyxJQUFBLGNBQVEsR0FBRSxDQUFDLENBQUMsQ0FBQTtZQUN6RSxJQUFLLElBQUEsYUFBTSxFQUFDLFVBQVUsQ0FBQyxFQUFHLENBQUM7Z0JBQ3ZCLE1BQU0sWUFBWSxHQUFHLElBQUEsV0FBSSxFQUFDLFVBQVUsRUFBQyxNQUFNLENBQUMsQ0FBQTtnQkFDNUMsT0FBTyxZQUFZLENBQUE7WUFDdkIsQ0FBQztpQkFBSSxDQUFDO2dCQUNGLGNBQU0sQ0FBQyxLQUFLLENBQUMsMEJBQTBCLFVBQVUsRUFBRSxDQUFDLENBQUE7WUFDeEQsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLEtBQVMsRUFBRSxDQUFDO1lBQ2pCLGNBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBQ2pFLENBQUM7SUFDTCxDQUFDO1NBQUksQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLElBQUEsNEJBQWMsR0FBUyxDQUFBO1FBQ3RDLE9BQU8sTUFBTSxDQUFBO0lBQ2pCLENBQUM7QUFDTCxDQUFDLENBQUE7QUFqQlksUUFBQSxVQUFVLGNBaUJ0QiJ9
|
||||
15
packages/osr-code-bot/constants.js
Normal file
15
packages/osr-code-bot/constants.js
Normal file
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MAX_FILE_SIZE = exports.EXCLUDE_GLOB = exports.MODULE_NAME = void 0;
|
||||
exports.MODULE_NAME = 'kbot';
|
||||
exports.EXCLUDE_GLOB = [
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/build/**",
|
||||
"**/coverage/**",
|
||||
"*.log",
|
||||
".kbot",
|
||||
".git"
|
||||
];
|
||||
exports.MAX_FILE_SIZE = 1024 * 1024 * 2;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBYSxRQUFBLFdBQVcsR0FBRyxNQUFNLENBQUE7QUFDcEIsUUFBQSxZQUFZLEdBQUc7SUFDeEIsb0JBQW9CO0lBQ3BCLFlBQVk7SUFDWixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxPQUFPO0lBQ1AsTUFBTTtDQUNULENBQUE7QUFDWSxRQUFBLGFBQWEsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQSJ9
|
||||
16
packages/osr-code-bot/dist/.npmignore
vendored
Normal file
16
packages/osr-code-bot/dist/.npmignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Ignore node_modules directory
|
||||
node_modules/
|
||||
|
||||
# Ignore log files
|
||||
*.log
|
||||
|
||||
# Ignore temporary files
|
||||
*.tmp
|
||||
|
||||
# Ignore coverage reports
|
||||
coverage/
|
||||
|
||||
.kbot
|
||||
*.exe
|
||||
package-lock.json
|
||||
tests
|
||||
205
packages/osr-code-bot/dist/README.md
vendored
Normal file
205
packages/osr-code-bot/dist/README.md
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
# @plastichub/code-bot
|
||||
|
||||
AI-powered command-line tool for code modifications and project management that supports multiple AI models and routers.
|
||||
|
||||
## Overview
|
||||
|
||||
Code-bot is a powerful CLI tool that helps developers automate code modifications, handle project management tasks, and integrate with various AI models for intelligent code and content assistance.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation Steps
|
||||
|
||||
KBot requires Node.js to run. It's recommended to use Node.js version 18 or higher.
|
||||
|
||||
1. Visit the official [Node.js website](https://nodejs.org/)
|
||||
2. Download the LTS (Long Term Support) version for your operating system
|
||||
3. Follow the installation wizard
|
||||
4. Verify installation by opening a terminal and running:
|
||||
```bash
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
### API Keys
|
||||
|
||||
KBot supports both OpenRouter and OpenAI APIs. You'll need at least one of these set up.
|
||||
|
||||
#### OpenRouter API (Recommended)
|
||||
|
||||
1. Visit [OpenRouter](https://openrouter.ai/)
|
||||
2. Sign up for an account
|
||||
3. Navigate to the API Keys section
|
||||
4. Create a new API key
|
||||
|
||||
#### OpenAI API (Optional)
|
||||
|
||||
1. Go to [OpenAI's platform](https://platform.openai.com/)
|
||||
2. Create an account or sign in
|
||||
3. Navigate to API keys section
|
||||
4. Create a new secret key
|
||||
|
||||
### Installation using Node NPM package manager
|
||||
|
||||
```bash
|
||||
npm install -g @plastichub/code-bot
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### API Keys Setup
|
||||
|
||||
Create configuration at `$HOME/.osr/.config.json` (or export OSR_CONFIG with path to config.json):
|
||||
|
||||
```json
|
||||
{
|
||||
"openrouter": {
|
||||
"key": "your-openrouter-key"
|
||||
},
|
||||
"openai": {
|
||||
"key": "your-openai-key"
|
||||
},
|
||||
"email": {
|
||||
"newsletter": {
|
||||
"host": "host.org",
|
||||
"port": 465,
|
||||
"debug": true,
|
||||
"transactionLog": true,
|
||||
"auth": {
|
||||
"user": "foo@bar.com",
|
||||
"pass": "pass"
|
||||
}
|
||||
}
|
||||
},
|
||||
"google": {
|
||||
"cse": "custom search engine id",
|
||||
"api_key": "google custom search api key"
|
||||
},
|
||||
"serpapi": {
|
||||
"key": "your SerpAPI key (optional, used for web searches(places, google maps))"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Preferences Setup
|
||||
|
||||
Optionally, create `.kbot/preferences.md` in your project directory to customize AI interactions:
|
||||
|
||||
```markdown
|
||||
## My Preferences
|
||||
|
||||
Gender : male
|
||||
Location : New York, USA (eg: `send me all saunas next to me`)
|
||||
Language : English
|
||||
Occupation : software developer, Typescript
|
||||
Age : 30+
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address : example@email.com (eg: `send me latest hacker news`)
|
||||
My wife's email address ("Anne") : example@email.com (eg: `send email to my wife, with latest local news')
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
- always Markdown
|
||||
- always add links
|
||||
- when sending emails, always add 'Best regards, [Your Name]'
|
||||
```
|
||||
# Command Line Parameters
|
||||
|
||||
This document describes all available command line parameters.
|
||||
|
||||
## Core Parameters
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `path` | Target directory | `.` | No |
|
||||
| `prompt` | The prompt. Supports file paths and environment variables | `./prompt.md` | No |
|
||||
| `output` | Optional output path for modified files (Tool mode only) | - | No |
|
||||
| `dst` | Optional destination path for the result, will substitute ${MODEL} and ${ROUTER} in the path. Used for "completion" mode | - | No |
|
||||
| `model` | AI model to use for processing | `anthropic/claude-3.5-sonnet` | No |
|
||||
| `router` | Router to use: openai or openrouter | `openrouter` | No |
|
||||
| `mode` | Chat completion mode: "completion" (without tools) or "tools" | `tools` | No |
|
||||
|
||||
## File Selection & Tools
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `include` | Glob patterns to match files for processing. Supports multiple patterns, e.g. `--include=src/*.tsx,src/*.ts --include=package.json` | - | No |
|
||||
| `disable` | Disable tools categories | `[]` | No |
|
||||
| `disableTools` | List of specific tools to disable | `[]` | No |
|
||||
|
||||
## Configuration & Profiles
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `profile` | Path to profile for variables. Supports environment variables | `${POLYMECH-ROOT}/profile.json` | No |
|
||||
| `env` | Environment (in profile) | `default` | No |
|
||||
| `config` | Path to JSON configuration file (API keys). Supports environment variables | - | No |
|
||||
| `preferences` | Path to preferences file (location, email, gender, etc). Supports environment variables | `./.kbot/preferences.md` | No |
|
||||
|
||||
## Debugging & Logging
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `logLevel` | Logging level for the application (0-4) | `2` | No |
|
||||
| `logs` | Logging directory | `./.kbot` | No |
|
||||
| `dump` | Create a script | - | No |
|
||||
| `dry` | Dry run - only write out parameters without making API calls | `false` | No |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Basic usage with default parameters
|
||||
kbot --prompt="What are the changes needed?"
|
||||
|
||||
# Specify model and router
|
||||
kbot --model="gpt-4" --router="openai" --prompt="Analyze this code"
|
||||
|
||||
# Process specific files
|
||||
kbot --include="src/*.ts" --include="package.json" --prompt="Check for security issues"
|
||||
|
||||
# Dry run with custom logging
|
||||
kbot --dry=true --logLevel=4 --prompt="Test run"
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Many path-based parameters support environment variables using the `${VARIABLE}` syntax:
|
||||
|
||||
- `${POLYMECH-ROOT}` - Root directory for Polymech
|
||||
- `${OSR-ROOT}` - Root directory for OSR
|
||||
|
||||
Example:
|
||||
```bash
|
||||
kbot --profile="${POLYMECH-ROOT}/custom-profile.json"
|
||||
```
|
||||
|
||||
# Working on Larger Directories
|
||||
|
||||
Since LLMs (Large Language Models) and providers are limited to very small 'context windows', it's necessary to feed them with smaller chunks instead. This document explains how to process larger directories efficiently.
|
||||
|
||||
## Directory Processing Example
|
||||
|
||||
Here's an example of how to walk through files and process them:
|
||||
|
||||
```bash
|
||||
osr-cli each --main='kbot \"read ${KEY} and translate to german, save in docs/language code/filename.md\" --include=\"${REL}\" --include=\".kbot/preferences.md\"' --list="./docs/*.md" --cwd=.
|
||||
```
|
||||
|
||||
### Parameter Explanation
|
||||
|
||||
- `each`: Command to process multiple files iteratively
|
||||
- `--main`: The main command (`kbot`) to execute for each file
|
||||
- `--include=\"${REL}\"` instructs kbot to include the current selected path
|
||||
- `--include=\".kbot/preferences.md\"` instructs kbot to include additional preferences about the task (eg: translation specifics)
|
||||
- `--list`: Specifies the file pattern to match
|
||||
- Supports include patterns (e.g., `"./docs/*.md"`)
|
||||
- `--cwd`: Sets the current working directory for the command execution. Default is the current directory (`.`)
|
||||
|
||||
**Note** requires `@plastichub/osr-cli-commons` to be installed globally:
|
||||
|
||||
```bash
|
||||
npm i -g @plastichub/osr-cli-commons
|
||||
```
|
||||
293
packages/osr-code-bot/dist/data/openai_models.json
vendored
Normal file
293
packages/osr-code-bot/dist/data/openai_models.json
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
{
|
||||
"timestamp": 1738015382028,
|
||||
"models": [
|
||||
{
|
||||
"id": "gpt-4o-audio-preview-2024-10-01",
|
||||
"object": "model",
|
||||
"created": 1727389042,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-audio-preview",
|
||||
"object": "model",
|
||||
"created": 1734387424,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview",
|
||||
"object": "model",
|
||||
"created": 1727659998,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o",
|
||||
"object": "model",
|
||||
"created": 1715367049,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-audio-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734115920,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-realtime-preview",
|
||||
"object": "model",
|
||||
"created": 1734387380,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "dall-e-2",
|
||||
"object": "model",
|
||||
"created": 1698798177,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo",
|
||||
"object": "model",
|
||||
"created": 1677610602,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "o1-preview-2024-09-12",
|
||||
"object": "model",
|
||||
"created": 1725648865,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-0125",
|
||||
"object": "model",
|
||||
"created": 1706048358,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-preview",
|
||||
"object": "model",
|
||||
"created": 1725648897,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-instruct",
|
||||
"object": "model",
|
||||
"created": 1692901427,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "babbage-002",
|
||||
"object": "model",
|
||||
"created": 1692634615,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-mini",
|
||||
"object": "model",
|
||||
"created": 1725649008,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-mini-2024-09-12",
|
||||
"object": "model",
|
||||
"created": 1725648979,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "whisper-1",
|
||||
"object": "model",
|
||||
"created": 1677532384,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "dall-e-3",
|
||||
"object": "model",
|
||||
"created": 1698785189,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview-2024-10-01",
|
||||
"object": "model",
|
||||
"created": 1727131766,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-1106-preview",
|
||||
"object": "model",
|
||||
"created": 1698957206,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "omni-moderation-latest",
|
||||
"object": "model",
|
||||
"created": 1731689265,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "omni-moderation-2024-09-26",
|
||||
"object": "model",
|
||||
"created": 1732734466,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-hd-1106",
|
||||
"object": "model",
|
||||
"created": 1699053533,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-2024-07-18",
|
||||
"object": "model",
|
||||
"created": 1721172717,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4",
|
||||
"object": "model",
|
||||
"created": 1687882411,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-hd",
|
||||
"object": "model",
|
||||
"created": 1699046015,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "davinci-002",
|
||||
"object": "model",
|
||||
"created": 1692634301,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-ada-002",
|
||||
"object": "model",
|
||||
"created": 1671217299,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo",
|
||||
"object": "model",
|
||||
"created": 1712361441,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "tts-1",
|
||||
"object": "model",
|
||||
"created": 1681940951,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-1106",
|
||||
"object": "model",
|
||||
"created": 1699053241,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-instruct-0914",
|
||||
"object": "model",
|
||||
"created": 1694122472,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-0125-preview",
|
||||
"object": "model",
|
||||
"created": 1706037612,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo-preview",
|
||||
"object": "model",
|
||||
"created": 1706037777,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-realtime-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734112601,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-audio-preview",
|
||||
"object": "model",
|
||||
"created": 1727460443,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-0613",
|
||||
"object": "model",
|
||||
"created": 1686588896,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-05-13",
|
||||
"object": "model",
|
||||
"created": 1715368132,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-3-small",
|
||||
"object": "model",
|
||||
"created": 1705948997,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo-2024-04-09",
|
||||
"object": "model",
|
||||
"created": 1712601677,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-1106",
|
||||
"object": "model",
|
||||
"created": 1698959748,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-16k",
|
||||
"object": "model",
|
||||
"created": 1683758102,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-audio-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734034239,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1733945430,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini",
|
||||
"object": "model",
|
||||
"created": 1721172741,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-3-large",
|
||||
"object": "model",
|
||||
"created": 1705953180,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-08-06",
|
||||
"object": "model",
|
||||
"created": 1722814719,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-11-20",
|
||||
"object": "model",
|
||||
"created": 1731975040,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "chatgpt-4o-latest",
|
||||
"object": "model",
|
||||
"created": 1723515131,
|
||||
"owned_by": "system"
|
||||
}
|
||||
]
|
||||
}
|
||||
5357
packages/osr-code-bot/dist/data/openrouter_models.json
vendored
Normal file
5357
packages/osr-code-bot/dist/data/openrouter_models.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
packages/osr-code-bot/dist/main_node.js
vendored
Normal file
3
packages/osr-code-bot/dist/main_node.js
vendored
Normal file
File diff suppressed because one or more lines are too long
173
packages/osr-code-bot/dist/main_node.js.LICENSE.txt
vendored
Normal file
173
packages/osr-code-bot/dist/main_node.js.LICENSE.txt
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
/*!
|
||||
* prr
|
||||
* (c) 2013 Rod Vagg <rod@vagg.org>
|
||||
* https://github.com/rvagg/prr
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
*
|
||||
* Copyright 2009-2017 Kris Kowal under the terms of the MIT
|
||||
* license found at https://github.com/kriskowal/q/blob/v1/LICENSE
|
||||
*
|
||||
* With parts by Tyler Close
|
||||
* Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
|
||||
* at http://www.opensource.org/licenses/mit-license.html
|
||||
* Forked at ref_send.js version: 2009-05-11
|
||||
*
|
||||
* With parts by Mark Miller
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Tmp
|
||||
*
|
||||
* Copyright (c) 2011-2017 KARASZI Istvan <github@spam.raszi.hu>
|
||||
*
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* fill-range <https://github.com/jonschlinkert/fill-range>
|
||||
*
|
||||
* Copyright (c) 2014-present, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* glob-base <https://github.com/jonschlinkert/glob-base>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* humanize-ms - index.js
|
||||
* Copyright(c) 2014 dead_horse <dead_horse@qq.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-dotfile <https://github.com/jonschlinkert/is-dotfile>
|
||||
*
|
||||
* Copyright (c) 2015-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-extglob <https://github.com/jonschlinkert/is-extglob>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-extglob <https://github.com/jonschlinkert/is-extglob>
|
||||
*
|
||||
* Copyright (c) 2014-2016, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-glob <https://github.com/jonschlinkert/is-glob>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-glob <https://github.com/jonschlinkert/is-glob>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* is-number <https://github.com/jonschlinkert/is-number>
|
||||
*
|
||||
* Copyright (c) 2014-present, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* mime-db
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015-2022 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* mime-types
|
||||
* Copyright(c) 2014 Jonathan Ong
|
||||
* Copyright(c) 2015 Douglas Christopher Wilson
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/*!
|
||||
* parse-glob <https://github.com/jonschlinkert/parse-glob>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* to-regex-range <https://github.com/micromatch/to-regex-range>
|
||||
*
|
||||
* Copyright (c) 2015-present, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */
|
||||
|
||||
/*! node-domexception. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
|
||||
|
||||
/*! queue-microtask. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! run-parallel. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! showdown v 2.1.0 - 21-04-2022 */
|
||||
|
||||
/*!*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* web-streams-polyfill v4.0.0-beta.3
|
||||
* Copyright 2021 Mattias Buelens, Diwank Singh Tomer and other contributors.
|
||||
* This code is released under the MIT license.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* @preserve
|
||||
* JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013)
|
||||
*
|
||||
* @author <a href="mailto:jensyt@gmail.com">Jens Taylor</a>
|
||||
* @see http://github.com/homebrewing/brauhaus-diff
|
||||
* @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
|
||||
* @see http://github.com/garycourt/murmurhash-js
|
||||
* @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
|
||||
* @see http://sites.google.com/site/murmurhash/
|
||||
*/
|
||||
1345
packages/osr-code-bot/dist/package-lock.json
generated
vendored
Normal file
1345
packages/osr-code-bot/dist/package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
packages/osr-code-bot/dist/package.json
vendored
Normal file
20
packages/osr-code-bot/dist/package.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@plastichub/kbot",
|
||||
"version": "1.1.7",
|
||||
"main": "main_node.js",
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"bin": {
|
||||
"kbot": "./main_node.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-emoji": "^2.2.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"puppeteer": "^23.11.1"
|
||||
}
|
||||
}
|
||||
196
packages/osr-code-bot/dist/stats/statistics.html
vendored
Normal file
196
packages/osr-code-bot/dist/stats/statistics.html
vendored
Normal file
File diff suppressed because one or more lines are too long
108
packages/osr-code-bot/docs_/README.md
Normal file
108
packages/osr-code-bot/docs_/README.md
Normal file
@ -0,0 +1,108 @@
|
||||
# @plastichub/code-bot
|
||||
|
||||
AI-powered command-line tool for code modifications and project management that supports multiple AI models and routers.
|
||||
|
||||
## Overview
|
||||
|
||||
Code-bot is a powerful CLI tool that helps developers automate code modifications, handle project management tasks, and integrate with various AI models for intelligent code and content assistance.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation Steps
|
||||
|
||||
KBot requires Node.js to run. It's recommended to use Node.js version 18 or higher.
|
||||
|
||||
1. Visit the official [Node.js website](https://nodejs.org/)
|
||||
2. Download the LTS (Long Term Support) version for your operating system
|
||||
3. Follow the installation wizard
|
||||
4. Verify installation by opening a terminal and running:
|
||||
```bash
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
### API Keys
|
||||
|
||||
KBot supports both OpenRouter and OpenAI APIs. You'll need at least one of these set up.
|
||||
|
||||
#### OpenRouter API (Recommended)
|
||||
|
||||
1. Visit [OpenRouter](https://openrouter.ai/)
|
||||
2. Sign up for an account
|
||||
3. Navigate to the API Keys section
|
||||
4. Create a new API key
|
||||
|
||||
#### OpenAI API (Optional)
|
||||
|
||||
1. Go to [OpenAI's platform](https://platform.openai.com/)
|
||||
2. Create an account or sign in
|
||||
3. Navigate to API keys section
|
||||
4. Create a new secret key
|
||||
|
||||
### Installation using Node NPM package manager
|
||||
|
||||
```bash
|
||||
npm install -g @plastichub/code-bot
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### API Keys Setup
|
||||
|
||||
Create configuration at `$HOME/.osr/.config.json` (or export OSR_CONFIG with path to config.json):
|
||||
|
||||
```json
|
||||
{
|
||||
"openrouter": {
|
||||
"key": "your-openrouter-key"
|
||||
},
|
||||
"openai": {
|
||||
"key": "your-openai-key"
|
||||
},
|
||||
"email": {
|
||||
"newsletter": {
|
||||
"host": "host.org",
|
||||
"port": 465,
|
||||
"debug": true,
|
||||
"transactionLog": true,
|
||||
"auth": {
|
||||
"user": "foo@bar.com",
|
||||
"pass": "pass"
|
||||
}
|
||||
}
|
||||
},
|
||||
"google": {
|
||||
"cse": "custom search engine id",
|
||||
"api_key": "google custom search api key"
|
||||
},
|
||||
"serpapi": {
|
||||
"key": "your SerpAPI key (optional, used for web searches(places, google maps))"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Preferences Setup
|
||||
|
||||
Optionally, create `.kbot/preferences.md` in your project directory to customize AI interactions:
|
||||
|
||||
```markdown
|
||||
## My Preferences
|
||||
|
||||
Gender : male
|
||||
Location : New York, USA (eg: `send me all saunas next to me`)
|
||||
Language : English
|
||||
Occupation : software developer, Typescript
|
||||
Age : 30+
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address : example@email.com (eg: `send me latest hacker news`)
|
||||
My wife's email address ("Anne") : example@email.com (eg: `send email to my wife, with latest local news')
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
- always Markdown
|
||||
- always add links
|
||||
- when sending emails, always add 'Best regards, [Your Name]'
|
||||
```
|
||||
28
packages/osr-code-bot/docs_/advanced.md
Normal file
28
packages/osr-code-bot/docs_/advanced.md
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
# Working on Larger Directories
|
||||
|
||||
Since LLMs (Large Language Models) and providers are limited to very small 'context windows', it's necessary to feed them with smaller chunks instead. This document explains how to process larger directories efficiently.
|
||||
|
||||
## Directory Processing Example
|
||||
|
||||
Here's an example of how to walk through files and process them:
|
||||
|
||||
```bash
|
||||
osr-cli each --main='kbot \"read ${KEY} and translate to german, save in docs/language code/filename.md\" --include=\"${REL}\" --include=\".kbot/preferences.md\"' --list="./docs/*.md" --cwd=.
|
||||
```
|
||||
|
||||
### Parameter Explanation
|
||||
|
||||
- `each`: Command to process multiple files iteratively
|
||||
- `--main`: The main command (`kbot`) to execute for each file
|
||||
- `--include=\"${REL}\"` instructs kbot to include the current selected path
|
||||
- `--include=\".kbot/preferences.md\"` instructs kbot to include additional preferences about the task (eg: translation specifics)
|
||||
- `--list`: Specifies the file pattern to match
|
||||
- Supports include patterns (e.g., `"./docs/*.md"`)
|
||||
- `--cwd`: Sets the current working directory for the command execution. Default is the current directory (`.`)
|
||||
|
||||
**Note** requires `@plastichub/osr-cli-commons` to be installed globally:
|
||||
|
||||
```bash
|
||||
npm i -g @plastichub/osr-cli-commons
|
||||
```
|
||||
18
packages/osr-code-bot/docs_/design.md
Normal file
18
packages/osr-code-bot/docs_/design.md
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
## CLI
|
||||
|
||||
- [ ] run
|
||||
- [ ] each
|
||||
|
||||
## Lib
|
||||
|
||||
- [ ] run
|
||||
|
||||
## Tool
|
||||
|
||||
- [ ] run
|
||||
|
||||
## API
|
||||
|
||||
- [ ] run
|
||||
|
||||
58
packages/osr-code-bot/docs_/docker.md
Normal file
58
packages/osr-code-bot/docs_/docker.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Docker Usage
|
||||
|
||||
## Quick Start
|
||||
|
||||
To quickly get started with kbot using Docker, run:
|
||||
|
||||
```bash
|
||||
docker run -d -p 8080:8080 plastichub/kbot
|
||||
```
|
||||
|
||||
This command:
|
||||
- Runs the container in detached mode (`-d`)
|
||||
- Maps port 8080 from the container to port 8080 on your host machine (`-p 8080:8080`)
|
||||
- Uses the official plastichub/kbot image
|
||||
|
||||
## Container Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The Docker container can be configured using environment variables:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 8080:8080 \
|
||||
-e OSR_CONFIG='{"openrouter":{"key":"your-key"}}' \
|
||||
plastichub/kbot
|
||||
```
|
||||
|
||||
### Volumes
|
||||
|
||||
To persist data or use custom configurations:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
-p 8080:8080 \
|
||||
-v $(pwd):/workspace \
|
||||
plastichub/kbot
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Example docker-compose.yml:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
kbot:
|
||||
image: plastichub/kbot
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/workspace
|
||||
```
|
||||
|
||||
Run with:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
6
packages/osr-code-bot/docs_/docker.sh
Normal file
6
packages/osr-code-bot/docs_/docker.sh
Normal file
@ -0,0 +1,6 @@
|
||||
echo "Start code-server in $(pwd)"
|
||||
docker run \
|
||||
-p 8080:8080 \
|
||||
-v "$(pwd -W)":/workspace \
|
||||
-v "C:\\Users\\zx\\.osr/:/root/.osr/" \
|
||||
plastichub/kbot
|
||||
145
packages/osr-code-bot/docs_/examples.md
Normal file
145
packages/osr-code-bot/docs_/examples.md
Normal file
@ -0,0 +1,145 @@
|
||||
# CLI Examples
|
||||
|
||||
## Basic Commands
|
||||
|
||||
### Modify Project Files
|
||||
|
||||
```bash
|
||||
# Basic project modification
|
||||
kbot "Add error handling to API endpoints"
|
||||
|
||||
# Using stdin for prompt
|
||||
echo "Add error handling to API endpoints" | kbot
|
||||
|
||||
# Pipe file content as prompt
|
||||
cat prompt.txt | kbot
|
||||
|
||||
|
||||
# Specify files using include patterns
|
||||
kbot --include "src/**/*.ts" "Update TypeScript types"
|
||||
|
||||
kbot "Add unit tests for src/commands/*" --include="./src/commands/*.ts"
|
||||
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# View modification history
|
||||
kbot log .
|
||||
```
|
||||
|
||||
### Node.js API Projects
|
||||
|
||||
```bash
|
||||
# Add API endpoints
|
||||
kbot --include "src/routes/*.ts" "Add authentication middleware"
|
||||
|
||||
# Update API models
|
||||
kbot --include "src/models/*.ts" "Add validation"
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### Using Profiles
|
||||
|
||||
Profiles allow you to define variables that can be used across your project and templates. These variables can be accessed using `${VARIABLE_NAME}` syntax in your tools and template partials.
|
||||
|
||||
```bash
|
||||
# Use a specific profile file
|
||||
kbot "Update configuration" --profile=./profiles/profile.json
|
||||
|
||||
# Use environment-specific variables
|
||||
kbot "Configure for Hugo release" --profile=./profiles/profile.json --env=hugo-release
|
||||
```
|
||||
|
||||
Example profile.json structure:
|
||||
```json
|
||||
{
|
||||
"variables" : {
|
||||
"foo": "bar"
|
||||
},
|
||||
"env": {
|
||||
"hugo-release": {
|
||||
"variables":{
|
||||
"GIT_USER": "hugo-deployer",
|
||||
"DEPLOY_TARGET": "production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Top-level variables are used as defaults
|
||||
- Environment-specific variables (specified by --env) override defaults
|
||||
- Variables can be used in tools and template partials using ${VARIABLE_NAME} syntax
|
||||
|
||||
### Custom Output Path
|
||||
|
||||
```bash
|
||||
# Save modifications to different directory
|
||||
kbot --output ./modified "Refactor code"
|
||||
```
|
||||
|
||||
### AI Model Selection
|
||||
|
||||
```bash
|
||||
# Use specific OpenAI model
|
||||
kbot --router openai --model gpt-4 "Optimize code"
|
||||
|
||||
# Use Anthropic Claude
|
||||
kbot --model anthropic/claude-3-opus "Add documentation"
|
||||
```
|
||||
|
||||
### Tool Control
|
||||
|
||||
```bash
|
||||
# Disable specific tools
|
||||
kbot --disable git "Update code without git commits"
|
||||
|
||||
# Disable multiple tool categories
|
||||
kbot --disable fs,npm,git "Analyze code only"
|
||||
```
|
||||
|
||||
### File Selection
|
||||
|
||||
```bash
|
||||
# Multiple include patterns
|
||||
kbot --include "src/**/*.ts" --include "test/**/*.ts" "Update types"
|
||||
|
||||
# Exclude patterns
|
||||
kbot --include "src/**/*.ts" --include "!src/generated/**" "Refactor code"
|
||||
```
|
||||
|
||||
### Environment and Profile
|
||||
|
||||
```bash
|
||||
# Use specific environment
|
||||
kbot --env production "Add production configs"
|
||||
|
||||
# Custom profile path
|
||||
kbot --profile ./custom-profile.json --env production
|
||||
```
|
||||
|
||||
### Scripting
|
||||
|
||||
```bash
|
||||
# Generate modification script
|
||||
kbot --dump ./modify-script.sh "Add types"
|
||||
```
|
||||
|
||||
### Input Types
|
||||
|
||||
The tool supports different types of input:
|
||||
|
||||
```bash
|
||||
# Text input through stdin
|
||||
echo "Add error handling" | kbot
|
||||
|
||||
# Piping files
|
||||
cat my-prompt.md | kbot
|
||||
|
||||
# Specifying a file
|
||||
kbot my-prompt.md
|
||||
```
|
||||
|
||||
2
packages/osr-code-bot/docs_/install.md
Normal file
2
packages/osr-code-bot/docs_/install.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Installation Guide for IKBot
|
||||
|
||||
69
packages/osr-code-bot/docs_/parameters.md
Normal file
69
packages/osr-code-bot/docs_/parameters.md
Normal file
@ -0,0 +1,69 @@
|
||||
# Command Line Parameters
|
||||
|
||||
This document describes all available command line parameters.
|
||||
|
||||
## Core Parameters
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `path` | Target directory | `.` | No |
|
||||
| `prompt` | The prompt. Supports file paths and environment variables | `./prompt.md` | No |
|
||||
| `output` | Optional output path for modified files (Tool mode only) | - | No |
|
||||
| `dst` | Optional destination path for the result, will substitute ${MODEL} and ${ROUTER} in the path. Used for "completion" mode | - | No |
|
||||
| `model` | AI model to use for processing | `anthropic/claude-3.5-sonnet` | No |
|
||||
| `router` | Router to use: openai or openrouter | `openrouter` | No |
|
||||
| `mode` | Chat completion mode: "completion" (without tools) or "tools" | `tools` | No |
|
||||
|
||||
## File Selection & Tools
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `include` | Glob patterns to match files for processing. Supports multiple patterns, e.g. `--include=src/*.tsx,src/*.ts --include=package.json` | - | No |
|
||||
| `disable` | Disable tools categories | `[]` | No |
|
||||
| `disableTools` | List of specific tools to disable | `[]` | No |
|
||||
|
||||
## Configuration & Profiles
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `profile` | Path to profile for variables. Supports environment variables | `${POLYMECH-ROOT}/profile.json` | No |
|
||||
| `env` | Environment (in profile) | `default` | No |
|
||||
| `config` | Path to JSON configuration file (API keys). Supports environment variables | - | No |
|
||||
| `preferences` | Path to preferences file (location, email, gender, etc). Supports environment variables | `./.kbot/preferences.md` | No |
|
||||
|
||||
## Debugging & Logging
|
||||
|
||||
| Parameter | Description | Default | Required |
|
||||
|-----------|-------------|---------|----------|
|
||||
| `logLevel` | Logging level for the application (0-4) | `2` | No |
|
||||
| `logs` | Logging directory | `./.kbot` | No |
|
||||
| `dump` | Create a script | - | No |
|
||||
| `dry` | Dry run - only write out parameters without making API calls | `false` | No |
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Basic usage with default parameters
|
||||
kbot --prompt="What are the changes needed?"
|
||||
|
||||
# Specify model and router
|
||||
kbot --model="gpt-4" --router="openai" --prompt="Analyze this code"
|
||||
|
||||
# Process specific files
|
||||
kbot --include="src/*.ts" --include="package.json" --prompt="Check for security issues"
|
||||
|
||||
# Dry run with custom logging
|
||||
kbot --dry=true --logLevel=4 --prompt="Test run"
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Many path-based parameters support environment variables using the `${VARIABLE}` syntax:
|
||||
|
||||
- `${POLYMECH-ROOT}` - Root directory for Polymech
|
||||
- `${OSR-ROOT}` - Root directory for OSR
|
||||
|
||||
Example:
|
||||
```bash
|
||||
kbot --profile="${POLYMECH-ROOT}/custom-profile.json"
|
||||
```
|
||||
49
packages/osr-code-bot/docs_/params_.md
Normal file
49
packages/osr-code-bot/docs_/params_.md
Normal file
@ -0,0 +1,49 @@
|
||||
# KBot Configuration Parameters
|
||||
|
||||
## Core Configuration
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| mode | enum (completion, tools, assistant) | tools | Chat completion mode: <br>- 'completion': no tool support, use --dst to save output <br>- 'tools': allows tools usage <br>- 'assistant': supports documents (PDF, DOCX, etc.) |
|
||||
| model | string | - | AI model to use for processing |
|
||||
| router | string | openrouter | Router to use: openai, openrouter or deepseek |
|
||||
| api_key | string | - | Explicit API key to use |
|
||||
| baseURL | string | - | Base URL for the API |
|
||||
|
||||
## Paths & Files
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| path | string | . | Target directory |
|
||||
| prompt | string | ./prompt.md | The prompt. Supports file paths and env variables |
|
||||
| output | string | - | Optional output path for modified files (Tool mode only) |
|
||||
| dst | string | - | Optional destination path for the result |
|
||||
| preferences | string | ./.kbot/preferences.md | Path to preferences file |
|
||||
| logs | string | ./.kbot | Logging directory |
|
||||
| config | string | - | Path to JSON configuration file |
|
||||
|
||||
## Tools & Filters
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| tools | string[] | [defaultTools] | List of tools to use |
|
||||
| disable | string[] | [] | Disable tools categories |
|
||||
| disableTools | string[] | [] | List of specific tools to disable |
|
||||
| filters | string[] | '' | Filters to apply to the output |
|
||||
|
||||
## Other Options
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| env | string | default | Environment (in profile) |
|
||||
| logLevel | number | 2 | Logging level for the application |
|
||||
| dump | string | - | Create a script |
|
||||
| variables | Record<string, string> | {} | Variables to use |
|
||||
| dry | boolean | false | Dry run - only write out parameters |
|
||||
|
||||
## File Selection
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | ---- | ------- | ----------- |
|
||||
| each | string | - | Glob pattern to run for each matching file |
|
||||
| include | string[] | - | Comma separated glob patterns or paths |
|
||||
81
packages/osr-code-bot/docs_/preferences.md
Normal file
81
packages/osr-code-bot/docs_/preferences.md
Normal file
@ -0,0 +1,81 @@
|
||||
# Personal Preferences Configuration
|
||||
|
||||
The `.kbot/preferences.md` file is used to store personal information and preferences that help the AI assistant provide more personalized and contextual responses.
|
||||
|
||||
## File Location
|
||||
|
||||
The preferences file should be located at:
|
||||
```
|
||||
.kbot/preferences.md
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
The preferences file uses Markdown format and is structured into several sections:
|
||||
|
||||
### Personal Information
|
||||
|
||||
```markdown
|
||||
|
||||
## My Preferences
|
||||
|
||||
Gender : [gender]
|
||||
Location : [city, country]
|
||||
Language : [primary language, preferred language]
|
||||
Occupation : [job title, specialties]
|
||||
Age : [age range]
|
||||
```
|
||||
|
||||
### Contact Information
|
||||
```markdown
|
||||
## Contacts
|
||||
|
||||
My email address : [your email]
|
||||
[Additional contacts with descriptions]
|
||||
```
|
||||
|
||||
### Content Preferences
|
||||
```markdown
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
|
||||
- [content formatting preferences]
|
||||
- [communication style preferences]
|
||||
- [email signature preferences]
|
||||
- [language preferences for specific contacts]
|
||||
- [search preferences]
|
||||
```
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Here's an example of a complete preferences file:
|
||||
|
||||
```markdown
|
||||
## My Preferences
|
||||
|
||||
Gender : male
|
||||
Location : Tarragona, Spain
|
||||
Language : German, prefer english
|
||||
Occupation : software developer, Typescript
|
||||
Age : 45+
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address : example@email.com
|
||||
My wife's email (Anne) : anne@email.com
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
|
||||
- always Markdown
|
||||
- always add links
|
||||
- when sending emails, always add 'kind regards, [Your Name]'
|
||||
- when sending emails to [Contact], always in [specific language]
|
||||
- when searching for news, always add links to videos, search via Google and other news outlets
|
||||
```
|
||||
|
||||
## Updating Preferences
|
||||
|
||||
You can update your preferences by directly editing the `.kbot/preferences.md` file. Changes take effect immediately for new interactions with the AI assistant.
|
||||
35
packages/osr-code-bot/docs_/todos.md
Normal file
35
packages/osr-code-bot/docs_/todos.md
Normal file
@ -0,0 +1,35 @@
|
||||
## Core
|
||||
|
||||
- history/session
|
||||
- run mode: streaming
|
||||
- extensions: gui
|
||||
|
||||
- logging : system, file logger, notification, popup
|
||||
|
||||
- filters: in/out (incl. tools)
|
||||
- input/output formats: md, csv, xls, docx, pdf
|
||||
|
||||
- splitters
|
||||
- pipes: n8n/nodered/stdio
|
||||
|
||||
- docs: custom help command
|
||||
|
||||
- router: ollama
|
||||
|
||||
- bundle: ESM & Deno
|
||||
|
||||
## Models
|
||||
|
||||
- task->match
|
||||
|
||||
## Prompt
|
||||
|
||||
- evaluation -> refine
|
||||
|
||||
## Tools
|
||||
|
||||
### Web
|
||||
|
||||
- external agents: https://github.com/Skyvern-AI/skyvern
|
||||
- multiple scrapers: puppeteer / cherio / API
|
||||
- Rapid API composer
|
||||
86
packages/osr-code-bot/docs_/tools.md
Normal file
86
packages/osr-code-bot/docs_/tools.md
Normal file
@ -0,0 +1,86 @@
|
||||
# LLM Tools Documentation
|
||||
|
||||
## Filesystem Tools (fs)
|
||||
|
||||
- `list_files`: List all files in a directory
|
||||
- Parameters:
|
||||
- directory: (string, required) Directory path to list files from
|
||||
- pattern: (string, optional) Glob pattern for filtering files
|
||||
|
||||
- `remove_file`: Remove a file at given path
|
||||
- Parameters:
|
||||
- path: (string, required) Path of the file to remove
|
||||
|
||||
- `rename_file`: Rename or move a file or directory
|
||||
- Parameters:
|
||||
- src: (string, required) Source path
|
||||
- dst: (string, required) Destination path
|
||||
|
||||
- `modify_project_files`: Modify existing project files
|
||||
- Parameters:
|
||||
- files: (array, required) Array of file objects with path and content
|
||||
|
||||
- `create_project_structure`: Create project structure with files and folders
|
||||
- Parameters:
|
||||
- files: (array, required) Array of file objects with path and content
|
||||
|
||||
- `create_file`: Creates a file, given a path and content
|
||||
- Parameters:
|
||||
- file: (object, required) Object containing path and content
|
||||
|
||||
- `read_file`: Read a file at given path
|
||||
- Parameters:
|
||||
- file: (object, required) Object containing path
|
||||
|
||||
## NPM Tools (npm)
|
||||
|
||||
- `build_project`: Build project using pnpm build command
|
||||
- Parameters: None required
|
||||
|
||||
- `run_npm`: Run an npm/pnpm command
|
||||
- Parameters:
|
||||
- command: (string, required) Command to run (e.g. install, test, etc)
|
||||
- args: (array, optional) Additional arguments for the command
|
||||
|
||||
- `install_dependency`: Install a dependency using npm
|
||||
- Parameters:
|
||||
- dependencies: (array, required) Array of dependency names
|
||||
|
||||
## Git Tools (git)
|
||||
|
||||
- `init_repository`: Initialize a new git repository if not exists
|
||||
- Parameters: None required
|
||||
|
||||
- `commit_files_git`: Commit files using git
|
||||
- Parameters:
|
||||
- files: (array, required) Array of file paths to commit
|
||||
- message: (string, required) Commit message
|
||||
|
||||
## Terminal Tools (terminal)
|
||||
|
||||
- `execute_command`: Execute a terminal command and capture output
|
||||
- Parameters:
|
||||
- command: (string, required) Command to execute
|
||||
- args: (array, optional) Command arguments
|
||||
- cwd: (string, optional) Working directory for command execution
|
||||
- background: (boolean, optional) Run command in background (non-blocking)
|
||||
- window: (boolean, optional) Open command in new terminal window
|
||||
- detached: (boolean, optional) Run process detached from parent
|
||||
|
||||
## Interactive Tools (interact)
|
||||
|
||||
- `ask_question`: Ask user a simple question and get response
|
||||
- Parameters:
|
||||
- question: (string, required) Question to ask the user
|
||||
- default: (string, optional) Default answer
|
||||
|
||||
- `choose_option`: Ask user to choose from multiple options
|
||||
- Parameters:
|
||||
- message: (string, required) Message to show the user
|
||||
- choices: (array, required) List of choices
|
||||
- multiple: (boolean, optional) Allow multiple selections
|
||||
|
||||
## User Tools (user)
|
||||
|
||||
- `capture_screen`: Capture a screenshot of the entire screen or a specific region
|
||||
- Parameters: None required
|
||||
139
packages/osr-code-bot/filters.js
Normal file
139
packages/osr-code-bot/filters.js
Normal file
File diff suppressed because one or more lines are too long
40
packages/osr-code-bot/index.js
Normal file
40
packages/osr-code-bot/index.js
Normal file
@ -0,0 +1,40 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.assistant_supported = exports.module_root = exports.run = exports.logger = void 0;
|
||||
const path_1 = __importDefault(require("path"));
|
||||
const osr_log_1 = require("@plastichub/osr-log");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const constants_1 = require("./constants");
|
||||
exports.logger = (0, osr_log_1.createLogger)('llm-tools');
|
||||
var run_1 = require("./commands/run");
|
||||
Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
|
||||
const isWindows = process.platform === 'win32';
|
||||
const module_root = () => path_1.default.resolve(path_1.default.join((0, osr_commons_1.get_var)(isWindows ? 'HOMEPATH' : 'HOME'), `.${constants_1.MODULE_NAME}`));
|
||||
exports.module_root = module_root;
|
||||
exports.assistant_supported = {
|
||||
".c": "text/x-c",
|
||||
".cpp": "text/x-c++",
|
||||
".cs": "text/x-csharp",
|
||||
".css": "text/css",
|
||||
".doc": "application/msword",
|
||||
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
".go": "text/x-golang",
|
||||
".html": "text/html",
|
||||
".java": "text/x-java",
|
||||
".js": "text/javascript",
|
||||
".json": "application/json",
|
||||
".md": "text/markdown",
|
||||
".pdf": "application/pdf",
|
||||
".php": "text/x-php",
|
||||
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
".py": "text/x-python", // sometimes text/x-script.python
|
||||
".rb": "text/x-ruby",
|
||||
".sh": "application/x-sh",
|
||||
".tex": "text/x-tex",
|
||||
".ts": "application/typescript",
|
||||
".txt": "text/plain"
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0RBQXVCO0FBR3ZCLGlEQUFrRDtBQUNsRCx5REFBaUU7QUFDakUsMkNBQXlDO0FBQzVCLFFBQUEsTUFBTSxHQUFvQixJQUFBLHNCQUFZLEVBQUMsV0FBVyxDQUFDLENBQUE7QUFDaEUsc0NBQW9DO0FBQTNCLDBGQUFBLEdBQUcsT0FBQTtBQUNaLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFBO0FBQ3ZDLE1BQU0sV0FBVyxHQUFHLEdBQUcsRUFBRSxDQUFDLGNBQUksQ0FBQyxPQUFPLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFBLHFCQUFPLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksdUJBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQTtBQUF6RyxRQUFBLFdBQVcsZUFBOEY7QUFFekcsUUFBQSxtQkFBbUIsR0FBMkI7SUFDdkQsSUFBSSxFQUFFLFVBQVU7SUFDaEIsTUFBTSxFQUFFLFlBQVk7SUFDcEIsS0FBSyxFQUFFLGVBQWU7SUFDdEIsTUFBTSxFQUFFLFVBQVU7SUFDbEIsTUFBTSxFQUFFLG9CQUFvQjtJQUM1QixPQUFPLEVBQUUseUVBQXlFO0lBQ2xGLEtBQUssRUFBRSxlQUFlO0lBQ3RCLE9BQU8sRUFBRSxXQUFXO0lBQ3BCLE9BQU8sRUFBRSxhQUFhO0lBQ3RCLEtBQUssRUFBRSxpQkFBaUI7SUFDeEIsT0FBTyxFQUFFLGtCQUFrQjtJQUMzQixLQUFLLEVBQUUsZUFBZTtJQUN0QixNQUFNLEVBQUUsaUJBQWlCO0lBQ3pCLE1BQU0sRUFBRSxZQUFZO0lBQ3BCLE9BQU8sRUFBRSwyRUFBMkU7SUFDcEYsS0FBSyxFQUFFLGVBQWUsRUFBVSxpQ0FBaUM7SUFDakUsS0FBSyxFQUFFLGFBQWE7SUFDcEIsS0FBSyxFQUFFLGtCQUFrQjtJQUN6QixNQUFNLEVBQUUsWUFBWTtJQUNwQixLQUFLLEVBQUUsd0JBQXdCO0lBQy9CLE1BQU0sRUFBRSxZQUFZO0NBQ3JCLENBQUMifQ==
|
||||
46
packages/osr-code-bot/main.js
Normal file
46
packages/osr-code-bot/main.js
Normal file
@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env node
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.logger = void 0;
|
||||
const yargs_1 = __importDefault(require("yargs"));
|
||||
const helpers_1 = require("yargs/helpers");
|
||||
const run_1 = require("./commands/run");
|
||||
const osr_log_1 = require("@plastichub/osr-log");
|
||||
const zod_schema_1 = require("./zod_schema");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const help_1 = __importDefault(require("./commands/help"));
|
||||
const examples_1 = require("./commands/examples");
|
||||
const init_1 = require("./commands/init");
|
||||
const build_1 = require("./commands/build");
|
||||
const fetch_1 = require("./commands/fetch");
|
||||
exports.logger = (0, osr_log_1.createLogger)('llm-tools');
|
||||
const modify = async (argv) => {
|
||||
const ret = await (0, run_1.run)(argv);
|
||||
return ret;
|
||||
};
|
||||
const yargOptions = {
|
||||
onKey: ((_yargs, key, options) => {
|
||||
switch (key) {
|
||||
case 'prompt':
|
||||
{
|
||||
return _yargs.positional(key, options);
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
||||
.command('init', 'Initialize KBot configuration', (yargs) => (0, osr_commons_1.toYargs)(yargs, (0, zod_schema_1.OptionsSchema)(), yargOptions), init_1.init)
|
||||
.command('modify [prompt]', 'Modify an existing project', (yargs) => (0, osr_commons_1.toYargs)(yargs, (0, zod_schema_1.OptionsSchema)(), yargOptions), modify)
|
||||
.command('types', 'Generate types', (yargs) => { }, (argv) => (0, zod_schema_1.types)())
|
||||
.command('build', 'Build kbot essentials', (yargs) => { }, (argv) => (0, build_1.build)())
|
||||
.command('fetch', "Fetch models, to $HOME/.kbot/", (yargs) => { }, (argv) => (0, fetch_1.fetch)())
|
||||
.command('help-md', 'Generate markdown help', (yargs) => { }, help_1.default)
|
||||
.command('examples', 'Show examples', (yargs) => { }, examples_1.examples)
|
||||
.command(['modify [prompt]', '$0'], 'Default command modify', (yargs) => (0, osr_commons_1.toYargs)(yargs, (0, zod_schema_1.OptionsSchema)(), yargOptions), modify)
|
||||
.help()
|
||||
.wrap(yargs_1.default.terminalWidth() - 20)
|
||||
.parse();
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQSxrREFBeUI7QUFDekIsMkNBQXVDO0FBQ3ZDLHdDQUFvQztBQUVwQyxpREFBa0Q7QUFDbEQsNkNBQW1EO0FBRW5ELHlEQUFpRDtBQUNqRCwyREFBeUM7QUFDekMsa0RBQThDO0FBQzlDLDBDQUFzQztBQUN0Qyw0Q0FBd0M7QUFDeEMsNENBQXdDO0FBRTNCLFFBQUEsTUFBTSxHQUFvQixJQUFBLHNCQUFZLEVBQUMsV0FBVyxDQUFDLENBQUE7QUFDaEUsTUFBTSxNQUFNLEdBQUcsS0FBSyxFQUFFLElBQWUsRUFBRSxFQUFFO0lBQ3ZDLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBQSxTQUFHLEVBQUMsSUFBaUIsQ0FBQyxDQUFBO0lBQ3hDLE9BQU8sR0FBRyxDQUFBO0FBQ1osQ0FBQyxDQUFBO0FBQ0QsTUFBTSxXQUFXLEdBQVE7SUFDdkIsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFO1FBQy9CLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFDWixLQUFLLFFBQVE7Z0JBQ1gsQ0FBQztvQkFDQyxPQUFPLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFBO2dCQUN4QyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQztDQUNILENBQUE7QUFFRCxJQUFBLGVBQUssRUFBQyxJQUFBLGlCQUFPLEVBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ3pCLE9BQU8sQ0FDTixNQUFNLEVBQ04sK0JBQStCLEVBQy9CLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFBLHFCQUFPLEVBQUMsS0FBSyxFQUFFLElBQUEsMEJBQWEsR0FBRSxFQUFFLFdBQVcsQ0FBQyxFQUN2RCxXQUFJLENBQ0w7S0FDQSxPQUFPLENBQ04saUJBQWlCLEVBQ2pCLDRCQUE0QixFQUM1QixDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBQSxxQkFBTyxFQUFDLEtBQUssRUFBRSxJQUFBLDBCQUFhLEdBQUUsRUFBRSxXQUFXLENBQUMsRUFDdkQsTUFBTSxDQUNQO0tBQ0EsT0FBTyxDQUNOLE9BQU8sRUFDUCxnQkFBZ0IsRUFDaEIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFDZCxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBQSxrQkFBSyxHQUFFLENBQ2xCO0tBQ0EsT0FBTyxDQUNOLE9BQU8sRUFDUCx1QkFBdUIsRUFDdkIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFDZCxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBQSxhQUFLLEdBQUUsQ0FDbEI7S0FDQSxPQUFPLENBQ04sT0FBTyxFQUNQLCtCQUErQixFQUMvQixDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUNkLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFBLGFBQUssR0FBRSxDQUNsQjtLQUNBLE9BQU8sQ0FDTixTQUFTLEVBQ1Qsd0JBQXdCLEVBQ3hCLENBQUMsS0FBSyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQ2QsY0FBVyxDQUNaO0tBQ0EsT0FBTyxDQUNOLFVBQVUsRUFDVixlQUFlLEVBQ2YsQ0FBQyxLQUFLLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFDZCxtQkFBUSxDQUNUO0tBQ0EsT0FBTyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLEVBQUUsd0JBQXdCLEVBQzFELENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFBLHFCQUFPLEVBQUMsS0FBSyxFQUFFLElBQUEsMEJBQWEsR0FBRSxFQUFFLFdBQVcsQ0FBQyxFQUFFLE1BQU0sQ0FBQztLQUNqRSxJQUFJLEVBQUU7S0FDTixJQUFJLENBQUMsZUFBSyxDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUNoQyxLQUFLLEVBQUUsQ0FBQSJ9
|
||||
97
packages/osr-code-bot/mime-handlers.js
Normal file
97
packages/osr-code-bot/mime-handlers.js
Normal file
@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.defaultMimeRegistry = exports.MimeHandlerRegistry = exports.TextHandler = exports.PDFHandler = exports.ImageHandler = void 0;
|
||||
const path = __importStar(require("path"));
|
||||
const source_1 = require("./source");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
class ImageHandler {
|
||||
handle(filePath, relativePath) {
|
||||
return {
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: (0, source_1.base64)(filePath)
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.ImageHandler = ImageHandler;
|
||||
class PDFHandler {
|
||||
handle(filePath, relativePath) {
|
||||
return {
|
||||
path: relativePath,
|
||||
content: (0, source_1.base64)(filePath),
|
||||
role: "user",
|
||||
name: path.parse(filePath).base
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.PDFHandler = PDFHandler;
|
||||
class TextHandler {
|
||||
handle(filePath, relativePath) {
|
||||
return {
|
||||
role: "user",
|
||||
path: relativePath,
|
||||
content: (0, read_1.sync)(filePath).toString()
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.TextHandler = TextHandler;
|
||||
class MimeHandlerRegistry {
|
||||
constructor() {
|
||||
this.handlers = new Map();
|
||||
}
|
||||
registerHandler(mimeType, handler) {
|
||||
this.handlers.set(mimeType, handler);
|
||||
}
|
||||
getHandler(mimeType) {
|
||||
// For mime types like 'image/png', try to match 'image/*' if specific type not found
|
||||
const [type] = mimeType.split('/');
|
||||
return this.handlers.get(mimeType) || this.handlers.get(`${type}/*`) || null;
|
||||
}
|
||||
}
|
||||
exports.MimeHandlerRegistry = MimeHandlerRegistry;
|
||||
// Create and export a pre-configured registry
|
||||
exports.defaultMimeRegistry = new MimeHandlerRegistry();
|
||||
// Register default handlers
|
||||
exports.defaultMimeRegistry.registerHandler('image/*', new ImageHandler());
|
||||
exports.defaultMimeRegistry.registerHandler('application/pdf', new PDFHandler());
|
||||
exports.defaultMimeRegistry.registerHandler('text/*', new TextHandler());
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWltZS1oYW5kbGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9taW1lLWhhbmRsZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUE0QjtBQUM1QixxQ0FBaUM7QUFDakMsOENBQWtEO0FBWWxELE1BQWEsWUFBWTtJQUN2QixNQUFNLENBQUMsUUFBZ0IsRUFBRSxZQUFvQjtRQUMzQyxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU07WUFDWixPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLFdBQVc7b0JBQ2pCLFNBQVMsRUFBRTt3QkFDVCxHQUFHLEVBQUUsSUFBQSxlQUFNLEVBQUMsUUFBUSxDQUFDO3FCQUN0QjtpQkFDRjthQUNGO1NBQ0YsQ0FBQTtJQUNILENBQUM7Q0FDRjtBQWRELG9DQWNDO0FBRUQsTUFBYSxVQUFVO0lBQ3JCLE1BQU0sQ0FBQyxRQUFnQixFQUFFLFlBQW9CO1FBQzNDLE9BQU87WUFDTCxJQUFJLEVBQUUsWUFBWTtZQUNsQixPQUFPLEVBQUUsSUFBQSxlQUFNLEVBQUMsUUFBUSxDQUFDO1lBQ3pCLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSTtTQUNoQyxDQUFBO0lBQ0gsQ0FBQztDQUNGO0FBVEQsZ0NBU0M7QUFFRCxNQUFhLFdBQVc7SUFDdEIsTUFBTSxDQUFDLFFBQWdCLEVBQUUsWUFBb0I7UUFDM0MsT0FBTztZQUNMLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLFlBQVk7WUFDbEIsT0FBTyxFQUFFLElBQUEsV0FBSSxFQUFDLFFBQVEsQ0FBQyxDQUFDLFFBQVEsRUFBRTtTQUNuQyxDQUFBO0lBQ0gsQ0FBQztDQUNGO0FBUkQsa0NBUUM7QUFFRCxNQUFhLG1CQUFtQjtJQUFoQztRQUNVLGFBQVEsR0FBOEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQVcxRCxDQUFDO0lBVEMsZUFBZSxDQUFDLFFBQWdCLEVBQUUsT0FBcUI7UUFDckQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxVQUFVLENBQUMsUUFBZ0I7UUFDekIscUZBQXFGO1FBQ3JGLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQztJQUMvRSxDQUFDO0NBQ0Y7QUFaRCxrREFZQztBQUVELDhDQUE4QztBQUNqQyxRQUFBLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQztBQUU3RCw0QkFBNEI7QUFDNUIsMkJBQW1CLENBQUMsZUFBZSxDQUFDLFNBQVMsRUFBRSxJQUFJLFlBQVksRUFBRSxDQUFDLENBQUM7QUFDbkUsMkJBQW1CLENBQUMsZUFBZSxDQUFDLGlCQUFpQixFQUFFLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQztBQUN6RSwyQkFBbUIsQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLElBQUksV0FBVyxFQUFFLENBQUMsQ0FBQyJ9
|
||||
5
packages/osr-code-bot/models/cache/openai.js
vendored
Normal file
5
packages/osr-code-bot/models/cache/openai.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
packages/osr-code-bot/models/cache/openrouter.js
vendored
Normal file
5
packages/osr-code-bot/models/cache/openrouter.js
vendored
Normal file
File diff suppressed because one or more lines are too long
293
packages/osr-code-bot/models/data/openai_models.json
Normal file
293
packages/osr-code-bot/models/data/openai_models.json
Normal file
@ -0,0 +1,293 @@
|
||||
{
|
||||
"timestamp": 1738177440286,
|
||||
"models": [
|
||||
{
|
||||
"id": "gpt-4o-audio-preview-2024-10-01",
|
||||
"object": "model",
|
||||
"created": 1727389042,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-audio-preview",
|
||||
"object": "model",
|
||||
"created": 1734387424,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-audio-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734115920,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-realtime-preview",
|
||||
"object": "model",
|
||||
"created": 1734387380,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "dall-e-2",
|
||||
"object": "model",
|
||||
"created": 1698798177,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo",
|
||||
"object": "model",
|
||||
"created": 1677610602,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "o1-preview-2024-09-12",
|
||||
"object": "model",
|
||||
"created": 1725648865,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-0125",
|
||||
"object": "model",
|
||||
"created": 1706048358,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-preview",
|
||||
"object": "model",
|
||||
"created": 1725648897,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-instruct",
|
||||
"object": "model",
|
||||
"created": 1692901427,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "babbage-002",
|
||||
"object": "model",
|
||||
"created": 1692634615,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-mini-2024-09-12",
|
||||
"object": "model",
|
||||
"created": 1725648979,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "whisper-1",
|
||||
"object": "model",
|
||||
"created": 1677532384,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "dall-e-3",
|
||||
"object": "model",
|
||||
"created": 1698785189,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview-2024-10-01",
|
||||
"object": "model",
|
||||
"created": 1727131766,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-1106-preview",
|
||||
"object": "model",
|
||||
"created": 1698957206,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "omni-moderation-latest",
|
||||
"object": "model",
|
||||
"created": 1731689265,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "omni-moderation-2024-09-26",
|
||||
"object": "model",
|
||||
"created": 1732734466,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-hd-1106",
|
||||
"object": "model",
|
||||
"created": 1699053533,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4",
|
||||
"object": "model",
|
||||
"created": 1687882411,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-0613",
|
||||
"object": "model",
|
||||
"created": 1686588896,
|
||||
"owned_by": "openai"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-hd",
|
||||
"object": "model",
|
||||
"created": 1699046015,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-2024-07-18",
|
||||
"object": "model",
|
||||
"created": 1721172717,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini",
|
||||
"object": "model",
|
||||
"created": 1721172741,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "davinci-002",
|
||||
"object": "model",
|
||||
"created": 1692634301,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-05-13",
|
||||
"object": "model",
|
||||
"created": 1715368132,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-ada-002",
|
||||
"object": "model",
|
||||
"created": 1671217299,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o",
|
||||
"object": "model",
|
||||
"created": 1715367049,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-08-06",
|
||||
"object": "model",
|
||||
"created": 1722814719,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo",
|
||||
"object": "model",
|
||||
"created": 1712361441,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "tts-1",
|
||||
"object": "model",
|
||||
"created": 1681940951,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "tts-1-1106",
|
||||
"object": "model",
|
||||
"created": 1699053241,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-instruct-0914",
|
||||
"object": "model",
|
||||
"created": 1694122472,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo-preview",
|
||||
"object": "model",
|
||||
"created": 1706037777,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-realtime-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734112601,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-audio-preview",
|
||||
"object": "model",
|
||||
"created": 1727460443,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-2024-11-20",
|
||||
"object": "model",
|
||||
"created": 1731975040,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-3-small",
|
||||
"object": "model",
|
||||
"created": 1705948997,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "chatgpt-4o-latest",
|
||||
"object": "model",
|
||||
"created": 1723515131,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo-2024-04-09",
|
||||
"object": "model",
|
||||
"created": 1712601677,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-1106",
|
||||
"object": "model",
|
||||
"created": 1698959748,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo-16k",
|
||||
"object": "model",
|
||||
"created": 1683758102,
|
||||
"owned_by": "openai-internal"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-audio-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1734034239,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview-2024-12-17",
|
||||
"object": "model",
|
||||
"created": 1733945430,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-realtime-preview",
|
||||
"object": "model",
|
||||
"created": 1727659998,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-0125-preview",
|
||||
"object": "model",
|
||||
"created": 1706037612,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "o1-mini",
|
||||
"object": "model",
|
||||
"created": 1725649008,
|
||||
"owned_by": "system"
|
||||
},
|
||||
{
|
||||
"id": "text-embedding-3-large",
|
||||
"object": "model",
|
||||
"created": 1705953180,
|
||||
"owned_by": "system"
|
||||
}
|
||||
]
|
||||
}
|
||||
5429
packages/osr-code-bot/models/data/openrouter_models.json
Normal file
5429
packages/osr-code-bot/models/data/openrouter_models.json
Normal file
File diff suppressed because it is too large
Load Diff
111
packages/osr-code-bot/models/index.js
Normal file
111
packages/osr-code-bot/models/index.js
Normal file
@ -0,0 +1,111 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.models = exports.models_dist = void 0;
|
||||
const chalk_1 = __importDefault(require("chalk"));
|
||||
const path = __importStar(require("path"));
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const index_1 = require("../index");
|
||||
const openrouter_1 = require("./openrouter");
|
||||
const openai_1 = require("./openai");
|
||||
const openai_2 = require("../models/openai");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const openai_3 = require("./cache/openai");
|
||||
const openrouter_2 = require("./cache/openrouter");
|
||||
const models_dist = () => {
|
||||
let or_models = openrouter_2.models;
|
||||
let oai_models = openai_3.models;
|
||||
let deepseek_models = [
|
||||
{
|
||||
"id": "deepseek-chat",
|
||||
"name": "deepseek-chat"
|
||||
},
|
||||
{
|
||||
"id": "deepseek-reasoner",
|
||||
"name": "deepseek-reasoner"
|
||||
},
|
||||
];
|
||||
const modelsOpenAIPath = path.resolve((0, index_1.module_root)(), 'openai.json');
|
||||
if ((0, exists_1.sync)(modelsOpenAIPath)) {
|
||||
oai_models = (0, read_1.sync)(modelsOpenAIPath, 'json');
|
||||
}
|
||||
const modelsRouterPath = path.resolve((0, index_1.module_root)(), 'openrouter.json');
|
||||
if ((0, exists_1.sync)(modelsRouterPath)) {
|
||||
or_models = (0, read_1.sync)(modelsRouterPath, 'json');
|
||||
}
|
||||
const models = [];
|
||||
models.push(chalk_1.default.magenta.bold('\n OpenRouter models:\n'));
|
||||
models.push(...(0, openrouter_1.listModelsAsStrings)(or_models));
|
||||
models.push(chalk_1.default.magenta.bold('\n OpenAI models:\n'));
|
||||
models.push(...(0, openai_1.listModelsAsStrings)(oai_models));
|
||||
models.push('-----\n');
|
||||
models.push(chalk_1.default.magenta.bold('\n Deepseek models:\n'));
|
||||
models.push(...(0, openai_1.listModelsAsStrings)(deepseek_models));
|
||||
models.push('-----\n');
|
||||
return models;
|
||||
};
|
||||
exports.models_dist = models_dist;
|
||||
const models = () => {
|
||||
const models = [];
|
||||
const openRouterPath = path.resolve(openrouter_1.CACHE_PATH);
|
||||
if (!(0, exists_1.sync)(openRouterPath)) {
|
||||
(0, openrouter_1.fetchOpenRouterModels)();
|
||||
}
|
||||
if ((0, exists_1.sync)(openRouterPath)) {
|
||||
const modelData = (0, read_1.sync)(openRouterPath, 'json');
|
||||
models.push(chalk_1.default.magenta.bold('\n OpenRouter models:\n'));
|
||||
models.push(...(0, openrouter_1.listModelsAsStrings)(modelData.models));
|
||||
}
|
||||
index_1.logger.debug('Openrouter models cache: ', openai_1.CACHE_PATH);
|
||||
const openAIPath = path.resolve(openai_1.CACHE_PATH);
|
||||
const config = (0, osr_commons_1.CONFIG_DEFAULT)();
|
||||
if (!(0, exists_1.sync)(openAIPath) && config?.openai?.key) {
|
||||
(0, openai_2.fetchOpenAIModels)(config.openai.key);
|
||||
}
|
||||
if ((0, exists_1.sync)(openAIPath)) {
|
||||
const modelData = (0, read_1.sync)(openAIPath, 'json');
|
||||
models.push(chalk_1.default.magenta.bold('\n OpenAI models:\n'));
|
||||
models.push(...(0, openai_1.listModelsAsStrings)(modelData.models));
|
||||
}
|
||||
index_1.logger.debug('OpenAI models cache: ', openai_1.CACHE_PATH);
|
||||
models.push('-----\n');
|
||||
return models;
|
||||
};
|
||||
exports.models = models;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbW9kZWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLGtEQUF5QjtBQUN6QiwyQ0FBNEI7QUFFNUIsOENBQWtEO0FBQ2xELGtEQUFzRDtBQUV0RCxvQ0FBOEM7QUFDOUMsNkNBQXVMO0FBQ3ZMLHFDQUFnSjtBQUNoSiw2Q0FBb0Q7QUFDcEQseURBQXdEO0FBRXhELDJDQUF1RDtBQUN2RCxtREFBK0Q7QUFFeEQsTUFBTSxXQUFXLEdBQUcsR0FBRyxFQUFFO0lBRTlCLElBQUksU0FBUyxHQUFHLG1CQUFnQixDQUFBO0lBQ2hDLElBQUksVUFBVSxHQUFHLGVBQVksQ0FBQTtJQUM3QixJQUFJLGVBQWUsR0FBRztRQUNsQjtZQUNFLElBQUksRUFBRSxlQUFlO1lBQ3JCLE1BQU0sRUFBRSxlQUFlO1NBQ3hCO1FBQ0Q7WUFDRSxJQUFJLEVBQUUsbUJBQW1CO1lBQ3pCLE1BQU0sRUFBRSxtQkFBbUI7U0FDNUI7S0FDSixDQUFBO0lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsbUJBQVcsR0FBRSxFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ25FLElBQUcsSUFBQSxhQUFNLEVBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1FBQzVCLFVBQVUsR0FBRyxJQUFBLFdBQUksRUFBQyxnQkFBZ0IsRUFBRSxNQUFNLENBQVEsQ0FBQTtJQUNwRCxDQUFDO0lBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsbUJBQVcsR0FBRSxFQUFFLGlCQUFpQixDQUFDLENBQUE7SUFDdkUsSUFBRyxJQUFBLGFBQU0sRUFBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDNUIsU0FBUyxHQUFHLElBQUEsV0FBSSxFQUFDLGdCQUFnQixFQUFFLE1BQU0sQ0FBUSxDQUFBO0lBQ25ELENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUE7SUFDM0IsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUE7SUFDMUQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUEsZ0NBQTZCLEVBQUMsU0FBZ0IsQ0FBQyxDQUFDLENBQUE7SUFFL0QsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUE7SUFDdEQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUEsNEJBQXlCLEVBQUMsVUFBaUIsQ0FBQyxDQUFDLENBQUE7SUFDNUQsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUV0QixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQTtJQUN4RCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBQSw0QkFBeUIsRUFBQyxlQUFzQixDQUFDLENBQUMsQ0FBQTtJQUNqRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3RCLE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQyxDQUFBO0FBcENZLFFBQUEsV0FBVyxlQW9DdkI7QUFJTSxNQUFNLE1BQU0sR0FBRyxHQUFHLEVBQUU7SUFDekIsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFBO0lBQzNCLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXFCLENBQUMsQ0FBQTtJQUMxRCxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUM1QixJQUFBLGtDQUFxQixHQUFFLENBQUE7SUFDekIsQ0FBQztJQUNELElBQUksSUFBQSxhQUFNLEVBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUMzQixNQUFNLFNBQVMsR0FBMkIsSUFBQSxXQUFJLEVBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBMkIsQ0FBQTtRQUNoRyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQTtRQUMxRCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBQSxnQ0FBNkIsRUFBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUNqRSxDQUFDO0lBQ0QsY0FBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxtQkFBaUIsQ0FBQyxDQUFBO0lBRTVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQWlCLENBQUMsQ0FBQTtJQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFBLDRCQUFjLEdBQVMsQ0FBQTtJQUN0QyxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsVUFBVSxDQUFDLElBQUksTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUMvQyxJQUFBLDBCQUFpQixFQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDdEMsQ0FBQztJQUVELElBQUksSUFBQSxhQUFNLEVBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLFNBQVMsR0FBdUIsSUFBQSxXQUFJLEVBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBdUIsQ0FBQTtRQUNwRixNQUFNLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQTtRQUN0RCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBQSw0QkFBeUIsRUFBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUM3RCxDQUFDO0lBQ0QsY0FBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsRUFBRSxtQkFBaUIsQ0FBQyxDQUFBO0lBQ3hELE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDdEIsT0FBTyxNQUFNLENBQUE7QUFDZixDQUFDLENBQUE7QUEzQlksUUFBQSxNQUFNLFVBMkJsQiJ9
|
||||
94
packages/osr-code-bot/models/openai.js
Normal file
94
packages/osr-code-bot/models/openai.js
Normal file
@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CACHE_PATH = void 0;
|
||||
exports.fetchOpenAIModels = fetchOpenAIModels;
|
||||
exports.listModelsAsStrings = listModelsAsStrings;
|
||||
const openai_1 = require("openai");
|
||||
const path = __importStar(require("path"));
|
||||
const index_1 = require("../index");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
exports.CACHE_PATH = path.resolve(path.join(path.parse(__filename).dir), 'data', 'openai_models.json');
|
||||
const CACHE_DURATION = 24 * 60 * 60 * 1000;
|
||||
async function readFromCache(cachePath = exports.CACHE_PATH) {
|
||||
try {
|
||||
if (!(0, exists_1.sync)(cachePath)) {
|
||||
return null;
|
||||
}
|
||||
const cacheData = (0, read_1.sync)(cachePath);
|
||||
const now = Date.now();
|
||||
if (now - cacheData.timestamp > CACHE_DURATION) {
|
||||
//return null
|
||||
}
|
||||
return cacheData.models;
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error('Error reading from cache:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function writeToCache(models, cachePath = exports.CACHE_PATH) {
|
||||
try {
|
||||
const cacheData = {
|
||||
timestamp: Date.now(),
|
||||
models
|
||||
};
|
||||
(0, write_1.sync)(cachePath, cacheData);
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error('Error writing to cache:', error);
|
||||
}
|
||||
}
|
||||
async function fetchOpenAIModels(apiKey, cachePath = exports.CACHE_PATH) {
|
||||
try {
|
||||
const openai = new openai_1.OpenAI({ apiKey });
|
||||
const response = await openai.models.list();
|
||||
const models = response.data;
|
||||
index_1.logger.info(`Fetched ${models.length} OpenAI models, to ${cachePath}`);
|
||||
writeToCache(models, cachePath);
|
||||
return models;
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error('Error fetching OpenAI models:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
function listModelsAsStrings(models) {
|
||||
models = models.sort((a, b) => a.id.localeCompare(b.id));
|
||||
return models.map((model) => `${model.id}`);
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21vZGVscy9vcGVuYWkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbURBLDhDQVlDO0FBQ0Qsa0RBR0M7QUFuRUQsbUNBQStCO0FBRS9CLDJDQUE0QjtBQUM1QixvQ0FBaUM7QUFFakMsa0RBQXNEO0FBQ3RELDhDQUFrRDtBQUNsRCxnREFBb0Q7QUFjdkMsUUFBQSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLG9CQUFvQixDQUFDLENBQUE7QUFDM0csTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFBO0FBRTFDLEtBQUssVUFBVSxhQUFhLENBQUMsWUFBb0Isa0JBQVU7SUFDdkQsSUFBSSxDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUE7UUFDZixDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBQSxXQUFJLEVBQUMsU0FBUyxDQUFpQixDQUFBO1FBQ2pELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtRQUN0QixJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsU0FBUyxHQUFHLGNBQWMsRUFBRSxDQUFDO1lBQzdDLGFBQWE7UUFDakIsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQTtJQUMzQixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNiLGNBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFDaEQsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDO0FBQ0wsQ0FBQztBQUNELFNBQVMsWUFBWSxDQUFDLE1BQXFCLEVBQUUsWUFBb0Isa0JBQVU7SUFDdkUsSUFBSSxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQWlCO1lBQzVCLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ3JCLE1BQU07U0FDVCxDQUFBO1FBQ0QsSUFBQSxZQUFLLEVBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsY0FBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0FBQ0wsQ0FBQztBQUNNLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxNQUFjLEVBQUUsWUFBb0Isa0JBQVU7SUFDbEYsSUFBSSxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ3JDLE1BQU0sUUFBUSxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUMzQyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFBO1FBQzVCLGNBQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxNQUFNLENBQUMsTUFBTSxzQkFBc0IsU0FBUyxFQUFFLENBQUMsQ0FBQTtRQUN0RSxZQUFZLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBQy9CLE9BQU8sTUFBTSxDQUFBO0lBQ2pCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsY0FBTSxDQUFDLEtBQUssQ0FBQywrQkFBK0IsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNwRCxNQUFNLEtBQUssQ0FBQTtJQUNmLENBQUM7QUFDTCxDQUFDO0FBQ0QsU0FBZ0IsbUJBQW1CLENBQUMsTUFBcUI7SUFDckQsTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUN4RCxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDaEQsQ0FBQyJ9
|
||||
117
packages/osr-code-bot/models/openrouter.js
Normal file
117
packages/osr-code-bot/models/openrouter.js
Normal file
@ -0,0 +1,117 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetchOpenRouterModels = exports.readFromCache = exports.CACHE_PATH = void 0;
|
||||
exports.findFreeModels = findFreeModels;
|
||||
exports.findFreePromptModels = findFreePromptModels;
|
||||
exports.findFreeCompletionModels = findFreeCompletionModels;
|
||||
exports.findFreeImageModels = findFreeImageModels;
|
||||
exports.listModelsAsStrings = listModelsAsStrings;
|
||||
const axios_1 = __importDefault(require("axios"));
|
||||
const path = __importStar(require("path"));
|
||||
const index_1 = require("../index");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const write_1 = require("@plastichub/fs/write");
|
||||
exports.CACHE_PATH = path.resolve(path.join(path.parse(__filename).dir), 'data', 'openrouter_models.json');
|
||||
const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
|
||||
const readFromCache = (cachePath = exports.CACHE_PATH) => {
|
||||
try {
|
||||
if (!(0, exists_1.sync)(cachePath)) {
|
||||
return null;
|
||||
}
|
||||
const cacheData = (0, read_1.sync)(cachePath, 'json');
|
||||
const now = Date.now();
|
||||
if (now - cacheData.timestamp > CACHE_DURATION) {
|
||||
//return null
|
||||
}
|
||||
return cacheData.models;
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error('Error reading from cache:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
exports.readFromCache = readFromCache;
|
||||
function writeToCache(models, cachePath = exports.CACHE_PATH) {
|
||||
const cacheData = {
|
||||
timestamp: Date.now(),
|
||||
models
|
||||
};
|
||||
(0, write_1.sync)(cachePath, cacheData);
|
||||
}
|
||||
const fetchOpenRouterModels = async (cachePath = exports.CACHE_PATH) => {
|
||||
try {
|
||||
// If no cache or expired, fetch from API
|
||||
const response = await axios_1.default.get('https://openrouter.ai/api/v1/models', {
|
||||
params: {
|
||||
// supported_parameters: 'tools'
|
||||
}
|
||||
});
|
||||
writeToCache(response.data.data);
|
||||
index_1.logger.debug(`Fetched ${response.data.data.length} OpenRouter models to ${cachePath}`);
|
||||
return response.data.data;
|
||||
}
|
||||
catch (error) {
|
||||
index_1.logger.error('Error fetching OpenRouter models:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
exports.fetchOpenRouterModels = fetchOpenRouterModels;
|
||||
function findFreeModels(models) {
|
||||
return models.filter((model) => model.pricing.prompt === 0 &&
|
||||
model.pricing.completion === 0 &&
|
||||
model.pricing.image === 0);
|
||||
}
|
||||
function findFreePromptModels(models) {
|
||||
return models.filter((model) => model.pricing.prompt === 0);
|
||||
}
|
||||
function findFreeCompletionModels(models) {
|
||||
return models.filter((model) => model.pricing.completion === 0);
|
||||
}
|
||||
function findFreeImageModels(models) {
|
||||
return models.filter((model) => model.pricing.image === 0);
|
||||
}
|
||||
function listModelsAsStrings(models) {
|
||||
models = models.sort((a, b) => a.name.localeCompare(b.name));
|
||||
return models.map((model) => {
|
||||
const isFree = model.name.includes('free');
|
||||
return `${model.id} | ${isFree ? 'free' : 'paid'}`;
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbnJvdXRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tb2RlbHMvb3BlbnJvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtRkEsd0NBT0M7QUFDRCxvREFFQztBQUVELDREQUVDO0FBRUQsa0RBRUM7QUFDRCxrREFNQztBQTVHRCxrREFBeUI7QUFDekIsMkNBQTZCO0FBQzdCLG9DQUFpQztBQUVqQyxrREFBc0Q7QUFDdEQsOENBQWtEO0FBQ2xELGdEQUFvRDtBQTZCdkMsUUFBQSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLHdCQUF3QixDQUFDLENBQUE7QUFFL0csTUFBTSxjQUFjLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUMsMkJBQTJCO0FBRWhFLE1BQU0sYUFBYSxHQUFHLENBQUMsWUFBb0Isa0JBQVUsRUFBcUMsRUFBRTtJQUNqRyxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN2QixPQUFPLElBQUksQ0FBQTtRQUNiLENBQUM7UUFDRCxNQUFNLFNBQVMsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsTUFBTSxDQUFpQixDQUFDO1FBQzFELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUMsU0FBUyxHQUFHLGNBQWMsRUFBRSxDQUFDO1lBQy9DLGFBQWE7UUFDZixDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUMsTUFBYSxDQUFDO0lBQ2pDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsY0FBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNoRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDLENBQUE7QUFmWSxRQUFBLGFBQWEsaUJBZXpCO0FBQ0QsU0FBUyxZQUFZLENBQUMsTUFBeUIsRUFBRSxZQUFvQixrQkFBVTtJQUM3RSxNQUFNLFNBQVMsR0FBaUI7UUFDOUIsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDckIsTUFBTTtLQUNQLENBQUM7SUFDRixJQUFBLFlBQUssRUFBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUE7QUFDN0IsQ0FBQztBQUVNLE1BQU0scUJBQXFCLEdBQUcsS0FBSyxFQUFFLFlBQW9CLGtCQUFVLEVBQThCLEVBQUU7SUFDeEcsSUFBSSxDQUFDO1FBQ0gseUNBQXlDO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLE1BQU0sZUFBSyxDQUFDLEdBQUcsQ0FDOUIscUNBQXFDLEVBQ3JDO1lBQ0UsTUFBTSxFQUFFO1lBQ04sZ0NBQWdDO2FBQ2pDO1NBQ0YsQ0FDRixDQUFBO1FBQ0QsWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDaEMsY0FBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0seUJBQXlCLFNBQVMsRUFBRSxDQUFDLENBQUE7UUFDdEYsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQWEsQ0FBQTtJQUNwQyxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLGNBQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFDeEQsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyxDQUFBO0FBbEJZLFFBQUEscUJBQXFCLHlCQWtCakM7QUFFRCxTQUFnQixjQUFjLENBQUMsTUFBeUI7SUFDdEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUNsQixDQUFDLEtBQUssRUFBRSxFQUFFLENBQ1IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUMxQixLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxDQUFDO1FBQzlCLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FDNUIsQ0FBQztBQUNKLENBQUM7QUFDRCxTQUFnQixvQkFBb0IsQ0FBQyxNQUF5QjtJQUM1RCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFFRCxTQUFnQix3QkFBd0IsQ0FBQyxNQUF5QjtJQUNoRSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFFRCxTQUFnQixtQkFBbUIsQ0FBQyxNQUF5QjtJQUMzRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFDRCxTQUFnQixtQkFBbUIsQ0FBQyxNQUF5QjtJQUMzRCxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQzVELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQzFCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQzFDLE9BQU8sR0FBRyxLQUFLLENBQUMsRUFBRSxNQUFNLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUNwRCxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMifQ==
|
||||
13482
packages/osr-code-bot/package-lock.json
generated
Normal file
13482
packages/osr-code-bot/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
80
packages/osr-code-bot/package.json
Normal file
80
packages/osr-code-bot/package.json
Normal file
@ -0,0 +1,80 @@
|
||||
{
|
||||
"name": "@plastichub/code-bot",
|
||||
"version": "0.3.4",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"bin": {
|
||||
"kbotd": "./main.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"dev": "tsc -p . --watch",
|
||||
"lint": "eslint src --ext .ts",
|
||||
"test": "vitest run",
|
||||
"test2:watch": "vitest",
|
||||
"test2:coverage": "vitest run --coverage",
|
||||
"webpack": "webpack --config webpack.config.js --stats-error-details",
|
||||
"exe:win": "cd dist && nexe -i main_node.js -o kbot.exe --build --temp=../../temp-kbot --verbose",
|
||||
"exe:lnx": "cd dist && nexe -i main_node.js -o kbot --build --temp=../../temp-kbot --verbose"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/ts-plugin": "1.10.4",
|
||||
"@plastichub/core": "^0.2.6",
|
||||
"@plastichub/fs": "^0.13.40",
|
||||
"@plastichub/osr-ai-tools": "file:../osr-ai-tools",
|
||||
"@plastichub/osr-commons": "0.5.3",
|
||||
"@plastichub/osr-log": "0.1.6",
|
||||
"axios": "1.7.9",
|
||||
"chalk": "4.0.0",
|
||||
"emojilib": "4.0.1",
|
||||
"free-astro-components": "1.1.1",
|
||||
"glob": "11.0.1",
|
||||
"marked": "14.1.4",
|
||||
"marked-terminal": "7.2.1",
|
||||
"mime-types": "2.1.35",
|
||||
"openai": "4.80.1",
|
||||
"p-map": "^4.0.0",
|
||||
"tslog": "^4.9.3",
|
||||
"yargs": "17.7.2",
|
||||
"zod": "3.24.1"
|
||||
},
|
||||
"keywords": [
|
||||
"ai",
|
||||
"code-assistant",
|
||||
"gpt",
|
||||
"bolt.new",
|
||||
"cursor",
|
||||
"code-generation",
|
||||
"pair-programming",
|
||||
"copilot",
|
||||
"code-completion",
|
||||
"natural-language-processing",
|
||||
"machine-learning",
|
||||
"autonomous-coding",
|
||||
"code-analysis",
|
||||
"code-suggestions",
|
||||
"code-intelligence",
|
||||
"refactoring-assistant",
|
||||
"code-documentation",
|
||||
"semantic-analysis",
|
||||
"code-review"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/node": "22.10.2",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"@vitest/coverage-v8": "^2.1.8",
|
||||
"eslint": "^8.57.1",
|
||||
"ts-json-schema-generator": "^2.3.0",
|
||||
"ts-loader": "9.5.1",
|
||||
"tsx": "^4.5.0",
|
||||
"typescript": "^5.7.2",
|
||||
"vitest": "^2.1.8",
|
||||
"webpack": "5.97.1",
|
||||
"webpack-cli": "6.0.1",
|
||||
"webpack-visualizer-plugin2": "1.1.0",
|
||||
"zod-to-json-schema": "3.24.1"
|
||||
}
|
||||
}
|
||||
4869
packages/osr-code-bot/pnpm-lock.yaml
Normal file
4869
packages/osr-code-bot/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
30
packages/osr-code-bot/preferences.md
Normal file
30
packages/osr-code-bot/preferences.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Personal Preferences Configuration
|
||||
|
||||
This file stores personal information and preferences to help the AI assistant provide more personalized and contextual responses.
|
||||
|
||||
## My Preferences
|
||||
|
||||
Gender : male
|
||||
Location : Sentmenat, Barcelona, Spain
|
||||
Language : German, prefer english
|
||||
Occupation : software developer, Typescript
|
||||
Age : 45+
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address : cgoflyn@gmail.com
|
||||
My wife's email (Anne) : barbier.anne13@gmail.com
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
|
||||
- always Markdown
|
||||
- always add links to sources
|
||||
- when sending emails, always add 'kind regards, Guenter'
|
||||
- when sending emails to Anne, always in french
|
||||
- when searching for news, always add links to videos, search via Google and other news outlets
|
||||
- always include the prompt in the result
|
||||
- Markdown
|
||||
- always new lines after headings
|
||||
- no need to test file for existence
|
||||
60
packages/osr-code-bot/profile.js
Normal file
60
packages/osr-code-bot/profile.js
Normal file
@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.load = void 0;
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const exists_1 = require("@plastichub/fs/exists");
|
||||
const path = __importStar(require("node:path"));
|
||||
const profile_1 = require("@plastichub/osr-commons/profile");
|
||||
const env_1 = require("./utils/env");
|
||||
const testPath = (profilePath) => {
|
||||
if (!profilePath) {
|
||||
return;
|
||||
}
|
||||
const ret = path.resolve((0, osr_commons_1.resolve)(profilePath, false, (0, env_1.env_vars)()));
|
||||
if ((0, exists_1.sync)(ret))
|
||||
return ret;
|
||||
};
|
||||
const load = async (options) => {
|
||||
let profile = { includes: [], variables: {}, env: {} };
|
||||
let profilePath = testPath(options.profile || path.join(options.logs, 'profile.json'));
|
||||
if (!profilePath || !(0, exists_1.sync)(profilePath) || !(0, osr_commons_1.isFile)(profilePath)) {
|
||||
return profile.variables;
|
||||
}
|
||||
profile = (0, profile_1.parseProfile)(profilePath, profile, { env: options.env || 'default' }) || profile;
|
||||
return profile.variables;
|
||||
};
|
||||
exports.load = load;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9wcm9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLHlEQUF5RDtBQUN6RCxrREFBc0Q7QUFDdEQsZ0RBQWlDO0FBQ2pDLDZEQUE4RDtBQUM5RCxxQ0FBc0M7QUFFdEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxXQUFtQixFQUFFLEVBQUU7SUFDckMsSUFBRyxDQUFDLFdBQVcsRUFBQyxDQUFDO1FBQ2IsT0FBTTtJQUNWLENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEscUJBQU8sRUFBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUEsY0FBUSxHQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ2hFLElBQUcsSUFBQSxhQUFNLEVBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxHQUFHLENBQUE7QUFDOUIsQ0FBQyxDQUFBO0FBRU0sTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLE9BQWtCLEVBQW1DLEVBQUU7SUFDOUUsSUFBSSxPQUFPLEdBQUcsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFBO0lBQ3RELElBQUksV0FBVyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFBO0lBQ3RGLElBQUcsQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFBLGFBQU0sRUFBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUEsb0JBQU0sRUFBQyxXQUFXLENBQUMsRUFBQyxDQUFDO1FBQzdELE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQTtJQUM1QixDQUFDO0lBQ0QsT0FBTyxHQUFHLElBQUEsc0JBQVksRUFBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUE7SUFDMUYsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFBO0FBQzVCLENBQUMsQ0FBQTtBQVJZLFFBQUEsSUFBSSxRQVFoQiJ9
|
||||
13
packages/osr-code-bot/profiles/profile.json
Normal file
13
packages/osr-code-bot/profiles/profile.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"includes": [],
|
||||
"variables": {
|
||||
"GIT_REPO": "https://git.polymech.io/",
|
||||
"GIT_USER": "osr-plastic"
|
||||
},
|
||||
"env": {
|
||||
"hugo-release":{
|
||||
"includes": [],
|
||||
"variables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
packages/osr-code-bot/prompt.js
Normal file
59
packages/osr-code-bot/prompt.js
Normal file
@ -0,0 +1,59 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.preferences = exports.prompt = void 0;
|
||||
const input_1 = require("./utils/input");
|
||||
const read_1 = require("@plastichub/fs/read");
|
||||
const osr_commons_1 = require("@plastichub/osr-commons");
|
||||
const path = __importStar(require("path"));
|
||||
const env_1 = require("./utils/env");
|
||||
const prompt = async (opts) => {
|
||||
const input = await (0, input_1.resolveQuery)(opts);
|
||||
return {
|
||||
role: "user",
|
||||
content: input || ''
|
||||
};
|
||||
};
|
||||
exports.prompt = prompt;
|
||||
const preferences = async (opts) => {
|
||||
const preferencesPath = path.resolve((0, osr_commons_1.resolve)(opts.preferences, false, (0, env_1.env_vars)()));
|
||||
const preferences = (0, read_1.sync)(preferencesPath, 'string');
|
||||
return {
|
||||
role: "user",
|
||||
content: preferences || ''
|
||||
};
|
||||
};
|
||||
exports.preferences = preferences;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL3Byb21wdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSx5Q0FBNEM7QUFFNUMsOENBQWtEO0FBQ2xELHlEQUFpRDtBQUNqRCwyQ0FBNEI7QUFDNUIscUNBQXNDO0FBQy9CLE1BQU0sTUFBTSxHQUFHLEtBQUssRUFBRSxJQUFlLEVBQW1ELEVBQUU7SUFDN0YsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFBLG9CQUFZLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFDdEMsT0FBTztRQUNILElBQUksRUFBRSxNQUFNO1FBQ1osT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO0tBQ3ZCLENBQUE7QUFDTCxDQUFDLENBQUE7QUFOWSxRQUFBLE1BQU0sVUFNbEI7QUFDTSxNQUFNLFdBQVcsR0FBRyxLQUFLLEVBQUUsSUFBZSxFQUFtRCxFQUFFO0lBQ2xHLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBQSxxQkFBTyxFQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLElBQUEsY0FBUSxHQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ2xGLE1BQU0sV0FBVyxHQUFHLElBQUEsV0FBSSxFQUFDLGVBQWUsRUFBRSxRQUFRLENBQVcsQ0FBQTtJQUM3RCxPQUFPO1FBQ0gsSUFBSSxFQUFFLE1BQU07UUFDWixPQUFPLEVBQUUsV0FBVyxJQUFJLEVBQUU7S0FDN0IsQ0FBQTtBQUNMLENBQUMsQ0FBQTtBQVBZLFFBQUEsV0FBVyxlQU92QiJ9
|
||||
196
packages/osr-code-bot/schema.json
Normal file
196
packages/osr-code-bot/schema.json
Normal file
File diff suppressed because one or more lines are too long
129
packages/osr-code-bot/schema_ui.json
Normal file
129
packages/osr-code-bot/schema_ui.json
Normal file
File diff suppressed because one or more lines are too long
3
packages/osr-code-bot/scripts/build.sh
Normal file
3
packages/osr-code-bot/scripts/build.sh
Normal file
@ -0,0 +1,3 @@
|
||||
npm run webpack
|
||||
sh scripts/update-readme.sh
|
||||
cp README.md dist/README.md
|
||||
8
packages/osr-code-bot/scripts/update-docker.sh
Normal file
8
packages/osr-code-bot/scripts/update-docker.sh
Normal file
@ -0,0 +1,8 @@
|
||||
kbotd modify \
|
||||
--path=. \
|
||||
--template=typescript \
|
||||
--query="./.kbot/todos-docker.md" \
|
||||
--include="./package.json" \
|
||||
--include="systems/*" \
|
||||
--include="!code-server*" \
|
||||
--disable="npm,terminal"
|
||||
7
packages/osr-code-bot/scripts/update-docs.sh
Normal file
7
packages/osr-code-bot/scripts/update-docs.sh
Normal file
@ -0,0 +1,7 @@
|
||||
kbotd modify \
|
||||
--prompt="./.kbot/docs.md" \
|
||||
--include="./src/commands/run.ts" \
|
||||
--include="./src/zod_schema.ts" \
|
||||
--logLevel=2
|
||||
|
||||
|
||||
3
packages/osr-code-bot/scripts/update-readme.sh
Normal file
3
packages/osr-code-bot/scripts/update-readme.sh
Normal file
@ -0,0 +1,3 @@
|
||||
cat ./docs_/README.md > ./README.md
|
||||
cat ./docs_/parameters.md >> ./README.md
|
||||
cat ./docs_/advanced.md >> ./README.md
|
||||
10
packages/osr-code-bot/scripts/update-todos.sh
Normal file
10
packages/osr-code-bot/scripts/update-todos.sh
Normal file
@ -0,0 +1,10 @@
|
||||
kbotd modify \
|
||||
--path=. \
|
||||
--prompt="./.kbot/todos.md" \
|
||||
--mode=completion \
|
||||
--router2=openai \
|
||||
--model=openai/gpt-4-32k \
|
||||
--include2="src/commands/run.ts" \
|
||||
--include2="src/commands/run-tools.ts" \
|
||||
--disable="npm,terminal,git,user,search,email" \
|
||||
--dst="./.kbot/todos-log.md"
|
||||
146
packages/osr-code-bot/source.js
Normal file
146
packages/osr-code-bot/source.js
Normal file
File diff suppressed because one or more lines are too long
78
packages/osr-code-bot/src/__tests__/config.test.ts
Normal file
78
packages/osr-code-bot/src/__tests__/config.test.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { loadConfig } from '../config'
|
||||
import { createClient } from '../client'
|
||||
|
||||
import * as fs from 'fs'
|
||||
|
||||
vi.mock('fs')
|
||||
vi.mock('@plastichub/osr-commons', () => ({
|
||||
CONFIG_DEFAULT: () => ({
|
||||
openrouter: { key: 'default-openrouter-key' },
|
||||
openai: { key: 'default-openai-key' }
|
||||
})
|
||||
}))
|
||||
vi.mock('.', () => ({
|
||||
logger: {
|
||||
error: vi.fn(),
|
||||
debug: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
describe('loadConfig', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks()
|
||||
})
|
||||
|
||||
it('should load config with API key from options', () => {
|
||||
const options = { api_key: 'test-key' }
|
||||
const result = loadConfig(options)
|
||||
expect(result.apiKey).toBe('test-key')
|
||||
})
|
||||
|
||||
it('should load config from JSON string', () => {
|
||||
const options = {
|
||||
config: '{"openrouter":{"key":"json-key"}}'
|
||||
}
|
||||
const result = loadConfig(options)
|
||||
expect(result.jsonConfig?.openrouter?.key).toBe('json-key')
|
||||
})
|
||||
|
||||
it('should load config from JSON file', () => {
|
||||
vi.mocked(fs.readFileSync).mockReturnValue('{"openrouter":{"key":"file-key"}}')
|
||||
const options = { config: 'config.json' }
|
||||
const result = loadConfig(options)
|
||||
expect(result.jsonConfig?.openrouter?.key).toBe('file-key')
|
||||
})
|
||||
|
||||
it('should handle invalid JSON config', () => {
|
||||
const options = { config: 'invalid-json' }
|
||||
const result = loadConfig(options)
|
||||
expect(result.jsonConfig).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('createClient', () => {
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks()
|
||||
process.env.API_KEY = undefined
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks()
|
||||
})
|
||||
|
||||
it('should create OpenRouter client with API key from options', () => {
|
||||
const client = createClient({ api_key: 'test-key', router: 'openrouter' })
|
||||
expect(client).toBeDefined()
|
||||
})
|
||||
|
||||
it('should create OpenAI client with API key from options', () => {
|
||||
const client = createClient({ api_key: 'test-key', router: 'openai' })
|
||||
expect(client).toBeDefined()
|
||||
})
|
||||
|
||||
it('should return undefined for unknown router', () => {
|
||||
const client = createClient({ api_key: 'test-key', router: 'unknown' as any })
|
||||
expect(client).toBeUndefined()
|
||||
})
|
||||
})
|
||||
98
packages/osr-code-bot/src/__tests__/templates.test.ts
Normal file
98
packages/osr-code-bot/src/__tests__/templates.test.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import {resolve_package_path, template_path, load } from '../templates'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { filesEx as include } from '@plastichub/osr-commons/_glob'
|
||||
import * as path from 'path'
|
||||
import { logger } from '../'
|
||||
|
||||
vi.mock('@plastichub/fs/exists')
|
||||
vi.mock('@plastichub/fs/read')
|
||||
vi.mock('@plastichub/osr-commons/_glob')
|
||||
vi.mock('@plastichub/osr-commons', () => ({
|
||||
resolve: vi.fn((path) => path),
|
||||
substitute: vi.fn((x, y) => y)
|
||||
}))
|
||||
vi.mock('path', async () => {
|
||||
const actual = await vi.importActual('path')
|
||||
return {
|
||||
...(actual as any),
|
||||
resolve: vi.fn((p) => p),
|
||||
join: vi.fn((...paths) => paths.join('/')),
|
||||
parse: vi.fn((p) => ({ name: p.split('/').pop()?.split('.')[0] }))
|
||||
}
|
||||
})
|
||||
vi.mock('../', () => ({
|
||||
logger: {
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
debug: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
describe('templates', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('template_path', () => {
|
||||
it('should return resolved path if template exists', () => {
|
||||
vi.mocked(exists).mockReturnValue(true)
|
||||
const options = { template: 'test-template', path: './' }
|
||||
const result = template_path(options)
|
||||
expect(result).toBe('test-template')
|
||||
expect(exists).toHaveBeenCalledWith('test-template')
|
||||
})
|
||||
|
||||
it('should check project path if direct path does not exist', () => {
|
||||
vi.mocked(exists).mockReturnValueOnce(false).mockReturnValueOnce(true)
|
||||
const options = { template: 'test-template', path: './project' }
|
||||
const result = template_path(options)
|
||||
expect(result).toBe('./project/test-template')
|
||||
})
|
||||
|
||||
it('should use template root if template not found in direct or project paths', () => {
|
||||
vi.mocked(exists).mockReturnValue(false)
|
||||
const options = {
|
||||
template: 'test-template',
|
||||
path: './project',
|
||||
templateRoot: '/templates'
|
||||
}
|
||||
const result = template_path(options)
|
||||
expect(result).toBe('/templates/ai-template-test-template')
|
||||
expect(logger.warn).toHaveBeenCalledWith('Template root /templates does not exist.')
|
||||
})
|
||||
|
||||
it('should use default template root if not provided', () => {
|
||||
vi.mocked(exists).mockReturnValue(false)
|
||||
const options = { template: 'test-template', path: './project' }
|
||||
const result = template_path(options)
|
||||
expect(result).toBe('${POLYMECH-ROOT}/ai-template-test-template')
|
||||
})
|
||||
})
|
||||
|
||||
describe('load', () => {
|
||||
it('should handle non-existent target directory', () => {
|
||||
vi.mocked(exists).mockReturnValue(false)
|
||||
const options = { path: './nonexistent' }
|
||||
const result = load(options)
|
||||
expect(result).toEqual({
|
||||
include: [
|
||||
"!node_modules/**/*",
|
||||
"!dist/**/*",
|
||||
"!build/**/*",
|
||||
"!coverage/**/*",
|
||||
"!*.log",
|
||||
"!.kbot",
|
||||
"!.git",
|
||||
"*"
|
||||
],
|
||||
messages: [],
|
||||
tools: ['fs', 'git', 'interact', 'terminal', 'search']
|
||||
})
|
||||
expect(logger.error).toHaveBeenCalledWith(
|
||||
'Target directory ./nonexistent does not exist.'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
60
packages/osr-code-bot/src/client.ts
Normal file
60
packages/osr-code-bot/src/client.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { OpenAI } from 'openai'
|
||||
import { logger } from './index'
|
||||
import { loadConfig } from './config'
|
||||
import { IKBotOptions } from './zod_types'
|
||||
|
||||
export const createClient = (options: IKBotOptions) => {
|
||||
const config = loadConfig(options)
|
||||
let apiKey: string = options.api_key
|
||||
if (!config) {
|
||||
logger.error(
|
||||
"Config not found in $HOME/.osr/config.json. " +
|
||||
"Optionally, export OSR_CONFIG with the path to the configuration file, "
|
||||
);
|
||||
return undefined
|
||||
}
|
||||
const router = options.router ?? "openrouter"
|
||||
let baseURL = options.baseURL
|
||||
if (!options.baseURL) {
|
||||
switch (router) {
|
||||
case "openrouter":
|
||||
apiKey = apiKey || config?.openrouter?.key;
|
||||
if (!options.baseURL) {
|
||||
baseURL = "https://openrouter.ai/api/v1"
|
||||
}
|
||||
break;
|
||||
case "openai":
|
||||
apiKey = apiKey || config?.openai?.key;
|
||||
break;
|
||||
case "deepseek":
|
||||
apiKey = apiKey || config?.deepseek?.key;
|
||||
if (!options.baseURL) {
|
||||
baseURL = "https://api.deepseek.com"
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!apiKey) {
|
||||
logger.error(`No ${router} key found. Please provide an "api_key", set it in the config, or pass it via JSON config.`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (router === "openrouter" && !options.model) {
|
||||
options.model = "anthropic/claude-3.5-sonnet"
|
||||
}
|
||||
|
||||
if (router === "openai" && !options.model) {
|
||||
options.model = "gpt-4o"
|
||||
}
|
||||
|
||||
if (router === "deepseek" && !options.model) {
|
||||
options.model = "deepseek-chat"
|
||||
}
|
||||
|
||||
logger.info(`Creating client with ${router} router, model ${options.model}, and API key ${apiKey} at ${baseURL}`)
|
||||
return new OpenAI({
|
||||
apiKey,
|
||||
baseURL,
|
||||
})
|
||||
}
|
||||
74
packages/osr-code-bot/src/collector.ts
Normal file
74
packages/osr-code-bot/src/collector.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import path from 'path'
|
||||
import OpenAI from 'openai'
|
||||
//import { ChatCompletion, ChatCompletionMessage, ChatCompletionMessageParam } from 'openai/resources'
|
||||
//import { } from 'openai/resources'
|
||||
import { ICollector } from '@plastichub/osr-ai-tools/types'
|
||||
import { winstonLogger, } from '@plastichub/osr-log'
|
||||
import { resolve } from '@plastichub/osr-commons'
|
||||
import { RunnableFunctionWithParse } from 'openai/lib/RunnableFunction'
|
||||
|
||||
import { IKBotOptions } from './zod_types'
|
||||
import { logger as loggerIntern } from './'
|
||||
import { ChatCompletion, ChatCompletionMessage, ChatCompletionMessageParam } from 'openai/resources/index.mjs'
|
||||
|
||||
export const collector = (options: IKBotOptions, client: OpenAI): ICollector => {
|
||||
return {
|
||||
//OpenAI
|
||||
onMessage: (message: ChatCompletionMessageParam) => {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'openai-message.json'))
|
||||
const logger = winstonLogger('collector:onMessage', logFile)
|
||||
logger.info(message)
|
||||
},
|
||||
onToolCall: async (message: ChatCompletionMessage.FunctionCall) => {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'tool-call.json'))
|
||||
const logger = winstonLogger('collector:onToolCall', logFile)
|
||||
try {
|
||||
const msg = { ...message, arguments: JSON.parse(message.arguments) }
|
||||
logger.debug(msg)
|
||||
} catch (e) {
|
||||
logger.debug(message)
|
||||
}
|
||||
},
|
||||
onFunctionCallResult: (message: string) => {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'tool-call-result.json'))
|
||||
const logger = winstonLogger('collector:onFunctionCallResult', logFile)
|
||||
try {
|
||||
const msg = { message: JSON.parse(message) }
|
||||
logger.debug(msg)
|
||||
} catch (e) {
|
||||
logger.debug(message)
|
||||
}
|
||||
},
|
||||
onChatCompletion: (message: ChatCompletion) => {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'completion.json'))
|
||||
const logger = winstonLogger('collector:onChatCompletion', logFile)
|
||||
logger.debug(message)
|
||||
},
|
||||
onContent: (content: string) => {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'content.json'))
|
||||
const logger = winstonLogger('collector:onContent', logFile)
|
||||
logger.debug(content)
|
||||
},
|
||||
onTool(category, name, args, result) {
|
||||
const logFile = path.resolve(path.join(resolve(options.logs), 'tool.json'))
|
||||
const logger = winstonLogger('collector:onTool', logFile)
|
||||
logger.debug({ category, name, args, result })
|
||||
},
|
||||
onToolBefore: async (ctx: RunnableFunctionWithParse<any>, args: any) => {
|
||||
try{
|
||||
loggerIntern.debug(`onToolBefore :${ctx.name}`)
|
||||
}catch(e){
|
||||
loggerIntern.error(e)
|
||||
}
|
||||
return args
|
||||
},
|
||||
onToolAfter: async (ctx: RunnableFunctionWithParse<any>, args: any, result?: any) => {
|
||||
try {
|
||||
loggerIntern.debug(`onToolAfter : ${ctx.name}`)
|
||||
} catch (e) {
|
||||
loggerIntern.error(e)
|
||||
}
|
||||
return result[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
40
packages/osr-code-bot/src/commands/build.ts
Normal file
40
packages/osr-code-bot/src/commands/build.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import path from 'path'
|
||||
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { logger } from '../'
|
||||
import { fetchOpenAIModels } from '../models/openai'
|
||||
import { fetchOpenRouterModels, OpenRouterModel } from '../models/openrouter'
|
||||
import { CONFIG_DEFAULT } from '@plastichub/osr-commons'
|
||||
import { arch } from 'os'
|
||||
|
||||
export const build = async () => {
|
||||
const examplesSrc = path.resolve(__dirname, '../docs_/examples.md')
|
||||
if(exists(examplesSrc)) {
|
||||
const examples = read(examplesSrc,'string') || ''
|
||||
const examplesPath = path.resolve(__dirname, '../src/docs-internal/examples.ts')
|
||||
write(examplesPath,`export const examples = ${JSON.stringify(examples)}`)
|
||||
logger.info(`Examples file generated " ${examplesPath}`)
|
||||
}else{
|
||||
logger.error(`Examples file not found ${examplesSrc}`)
|
||||
}
|
||||
|
||||
const config = CONFIG_DEFAULT() as any
|
||||
|
||||
const modelsOpenAI = await fetchOpenAIModels(config.openai.key)
|
||||
const modelsOpenRouter = (await fetchOpenRouterModels()).map((model) => {
|
||||
return {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
pricing: model.pricing,
|
||||
context: model.context,
|
||||
created: model.created
|
||||
}
|
||||
})
|
||||
const modelsOpenAIPath = path.resolve(__dirname, '../src/models/cache/openai.ts')
|
||||
write(modelsOpenAIPath,`export const models = ${JSON.stringify(modelsOpenAI)}`)
|
||||
|
||||
const modelsOpenRouterPath = path.resolve(__dirname, '../src/models/cache/openrouter.ts')
|
||||
write(modelsOpenRouterPath,`export const models = ${JSON.stringify(modelsOpenRouter)}`)
|
||||
}
|
||||
12
packages/osr-code-bot/src/commands/examples.ts
Normal file
12
packages/osr-code-bot/src/commands/examples.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { marked } from 'marked'
|
||||
import { markedTerminal } from 'marked-terminal'
|
||||
import { examples as content } from '../docs-internal/examples'
|
||||
|
||||
export const examples = () => {
|
||||
marked.use(markedTerminal(
|
||||
{
|
||||
emoji: false,
|
||||
}
|
||||
))
|
||||
process.stdout.write(marked(content) as string)
|
||||
}
|
||||
34
packages/osr-code-bot/src/commands/fetch.ts
Normal file
34
packages/osr-code-bot/src/commands/fetch.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import path from 'path'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
import { logger, module_root } from '..'
|
||||
import { fetchOpenAIModels } from '../models/openai'
|
||||
import { fetchOpenRouterModels } from '../models/openrouter'
|
||||
import { CONFIG_DEFAULT } from '@plastichub/osr-commons'
|
||||
|
||||
export const fetch = async () => {
|
||||
|
||||
const config = CONFIG_DEFAULT() as any
|
||||
if (config.openai && config.openai.key) {
|
||||
const modelsOpenAI = await fetchOpenAIModels(config.openai.key)
|
||||
if (modelsOpenAI) {
|
||||
const modelsOpenAIPath = path.resolve(module_root(), 'openai.json')
|
||||
write(modelsOpenAIPath, modelsOpenAI)
|
||||
logger.info(`Fetched ${modelsOpenAI.length} OpenAI models, to ${modelsOpenAIPath}`)
|
||||
} else {
|
||||
logger.error(`Failed to fetch OpenAI models`)
|
||||
}
|
||||
}
|
||||
|
||||
const modelsOpenRouter = (await fetchOpenRouterModels()).map((model) => {
|
||||
return {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
pricing: model.pricing,
|
||||
context: model.context,
|
||||
created: model.created
|
||||
}
|
||||
})
|
||||
const modelsOpenRouterPath = path.resolve(module_root(), 'openrouter.json')
|
||||
write(modelsOpenRouterPath, modelsOpenRouter)
|
||||
logger.info(`Fetched ${modelsOpenRouter.length} OpenRouter models, to ${modelsOpenRouterPath}`)
|
||||
}
|
||||
257
packages/osr-code-bot/src/commands/handlers/audio-handler.ts
Normal file
257
packages/osr-code-bot/src/commands/handlers/audio-handler.ts
Normal file
@ -0,0 +1,257 @@
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
import { BaseHandler } from './base-handler';
|
||||
import { logger } from '../../index'
|
||||
import { createClient } from '../../client';
|
||||
import { toFile } from "openai"
|
||||
import { IKBotOptions } from '../../zod_types';
|
||||
/**
|
||||
* Hex bytes for the "ID3" tag (ID3v2 header).
|
||||
* Typically found at the beginning of an MP3 file that contains ID3 metadata.
|
||||
*/
|
||||
export const ID3_HEADER_BYTES = new Uint8Array([0x49, 0x44, 0x33]);
|
||||
|
||||
/**
|
||||
* Possible first two bytes (frame sync) of an MP3 file without an ID3 tag.
|
||||
* Commonly:
|
||||
* - 0xFF 0xFB for MPEG-1 Layer III
|
||||
* - 0xFF 0xF3 for MPEG-2 Layer III
|
||||
* - 0xFF 0xF2 for MPEG-2.5 Layer III
|
||||
*/
|
||||
export const MP3_FRAME_SYNC_PATTERNS: Uint8Array[] = [
|
||||
new Uint8Array([0xFF, 0xFB]),
|
||||
new Uint8Array([0xFF, 0xF3]),
|
||||
new Uint8Array([0xFF, 0xF2]),
|
||||
];
|
||||
|
||||
const isMp3File = (fileBuffer: ArrayBuffer): boolean => {
|
||||
const byteView = new Uint8Array(fileBuffer);
|
||||
|
||||
// Check if the file starts with ID3 bytes
|
||||
if (
|
||||
byteView[0] === ID3_HEADER_BYTES[0] &&
|
||||
byteView[1] === ID3_HEADER_BYTES[1] &&
|
||||
byteView[2] === ID3_HEADER_BYTES[2]
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Or check if it starts with a known frame sync pattern
|
||||
return MP3_FRAME_SYNC_PATTERNS.some((pattern) => {
|
||||
return byteView[0] === pattern[0] && byteView[1] === pattern[1];
|
||||
});
|
||||
}
|
||||
/**
|
||||
* "RIFF" in ASCII
|
||||
* 0x52 = R
|
||||
* 0x49 = I
|
||||
* 0x46 = F
|
||||
* 0x46 = F
|
||||
*/
|
||||
export const WAV_RIFF_HEADER = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
|
||||
|
||||
/**
|
||||
* "WAVE" in ASCII
|
||||
* 0x57 = W
|
||||
* 0x41 = A
|
||||
* 0x56 = V
|
||||
* 0x45 = E
|
||||
*/
|
||||
export const WAV_WAVE_HEADER = new Uint8Array([0x57, 0x41, 0x56, 0x45]);
|
||||
|
||||
/**
|
||||
* Checks if the provided file buffer is likely a WAV file.
|
||||
* - Must start with "RIFF" (bytes 0–3)
|
||||
* - Must have "WAVE" at bytes 8–11
|
||||
*/
|
||||
export function isWavFile(fileBuffer: ArrayBuffer): boolean {
|
||||
const byteView = new Uint8Array(fileBuffer);
|
||||
|
||||
// Safety check: we need at least 12 bytes to validate "RIFF" + "WAVE" positions
|
||||
if (byteView.length < 12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the "RIFF" part (bytes 0..3)
|
||||
if (
|
||||
byteView[0] !== WAV_RIFF_HEADER[0] ||
|
||||
byteView[1] !== WAV_RIFF_HEADER[1] ||
|
||||
byteView[2] !== WAV_RIFF_HEADER[2] ||
|
||||
byteView[3] !== WAV_RIFF_HEADER[3]
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the "WAVE" part (bytes 8..11)
|
||||
if (
|
||||
byteView[8] !== WAV_WAVE_HEADER[0] ||
|
||||
byteView[9] !== WAV_WAVE_HEADER[1] ||
|
||||
byteView[10] !== WAV_WAVE_HEADER[2] ||
|
||||
byteView[11] !== WAV_WAVE_HEADER[3]
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* "ftyp" in ASCII (0x66 = f, 0x74 = t, 0x79 = y, 0x70 = p).
|
||||
*/
|
||||
export const FTYP_BOX_HEADER = new Uint8Array([0x66, 0x74, 0x79, 0x70]);
|
||||
|
||||
/**
|
||||
* Common major/compatible brand signatures for M4A.
|
||||
* - "M4A " (0x4D 0x34 0x41 0x20)
|
||||
* - "mp42" (0x6D 0x70 0x34 0x32)
|
||||
* - "isom" (0x69 0x73 0x6F 0x6D)
|
||||
*
|
||||
* Note: Some M4A files might list different/older brand combos,
|
||||
* but these are the most common.
|
||||
*/
|
||||
export const M4A_BRANDS: Uint8Array[] = [
|
||||
new Uint8Array([0x4D, 0x34, 0x41, 0x20]), // "M4A "
|
||||
new Uint8Array([0x6D, 0x70, 0x34, 0x32]), // "mp42"
|
||||
new Uint8Array([0x69, 0x73, 0x6F, 0x6D]), // "isom"
|
||||
];
|
||||
|
||||
/**
|
||||
* Checks if the provided file buffer likely represents an M4A.
|
||||
*
|
||||
* Basic check:
|
||||
* 1. Must have at least 12 bytes (4 bytes size + "ftyp" + brand).
|
||||
* 2. Bytes [4..7] should be "f t y p".
|
||||
* 3. Bytes [8..11] should match a known brand (e.g., "M4A ", "mp42", "isom").
|
||||
*
|
||||
* @param fileBuffer The raw file data as an ArrayBuffer
|
||||
* @returns boolean indicating if this is likely an M4A
|
||||
*/
|
||||
export function isM4AFile(fileBuffer: ArrayBuffer): boolean {
|
||||
const byteView = new Uint8Array(fileBuffer);
|
||||
|
||||
// We need at least 12 bytes to check: [0..3] size, [4..7] 'ftyp', [8..11] brand
|
||||
if (byteView.length < 12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that bytes [4..7] == "ftyp"
|
||||
if (
|
||||
byteView[4] !== FTYP_BOX_HEADER[0] ||
|
||||
byteView[5] !== FTYP_BOX_HEADER[1] ||
|
||||
byteView[6] !== FTYP_BOX_HEADER[2] ||
|
||||
byteView[7] !== FTYP_BOX_HEADER[3]
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the 4-byte brand at [8..11]
|
||||
const brandBytes = byteView.subarray(8, 12);
|
||||
|
||||
// Check if brandBytes matches any known brand
|
||||
const matchesKnownBrand = M4A_BRANDS.some((brand) => {
|
||||
return (
|
||||
brandBytes[0] === brand[0] &&
|
||||
brandBytes[1] === brand[1] &&
|
||||
brandBytes[2] === brand[2] &&
|
||||
brandBytes[3] === brand[3]
|
||||
);
|
||||
});
|
||||
|
||||
return matchesKnownBrand;
|
||||
}
|
||||
|
||||
const createBuffer = (path: string): Buffer | null => {
|
||||
try {
|
||||
const buffer = fs.readFileSync(path)
|
||||
return buffer;
|
||||
} catch (error) {
|
||||
console.error('Error creating buffer:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
const getAudioFileType = (filePath: string | Buffer): { fileName: string; mimeType: string } => {
|
||||
const ext = typeof filePath === 'string' ? path.extname(filePath).toLowerCase() : null;
|
||||
if (ext) {
|
||||
switch (ext) {
|
||||
case '.mp3':
|
||||
return { fileName: 'audio.mp3', mimeType: 'audio/mpeg' };
|
||||
case '.m4a':
|
||||
return { fileName: 'audio.m4a', mimeType: 'audio/m4a' };
|
||||
case '.wav':
|
||||
return { fileName: 'audio.wav', mimeType: 'audio/wav' };
|
||||
}
|
||||
}
|
||||
|
||||
// If no ext or not a string (buffer), detect from content
|
||||
const buffer = Buffer.isBuffer(filePath) ? filePath : fs.readFileSync(filePath as string);
|
||||
if (isMp3File(buffer)) {
|
||||
return { fileName: 'audio.mp3', mimeType: 'audio/mpeg' };
|
||||
} else if (isM4AFile(buffer)) {
|
||||
return { fileName: 'audio.m4a', mimeType: 'audio/m4a' };
|
||||
} else if (isWavFile(buffer)) {
|
||||
return { fileName: 'audio.wav', mimeType: 'audio/wav' };
|
||||
}
|
||||
throw new Error('Unsupported audio format');
|
||||
};
|
||||
|
||||
export class AudioHandler extends BaseHandler {
|
||||
private options: IKBotOptions;
|
||||
|
||||
constructor(options: IKBotOptions) {
|
||||
super();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
async canHandle(content: Buffer | string, isPath: boolean): Promise<boolean> {
|
||||
if (isPath) {
|
||||
// Check file extension for paths
|
||||
const ext = path.extname(content as string).toLowerCase();
|
||||
return ['.wav', '.mp3', '.m4a'].includes(ext);
|
||||
}
|
||||
|
||||
// Check content type for buffers
|
||||
if (!Buffer.isBuffer(content)) return false;
|
||||
return isMp3File(content) || isWavFile(content) || isM4AFile(content);
|
||||
}
|
||||
|
||||
async handle(content: Buffer | string, isPath: boolean): Promise<string> {
|
||||
const client = createClient({...this.options,router: 'openai'})
|
||||
if (!client) {
|
||||
throw new Error('Failed to create OpenAI client for audio transcription');
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
let audioType: { fileName: string; mimeType: string };
|
||||
|
||||
if (isPath) {
|
||||
const filePath = content as string;
|
||||
audioType = getAudioFileType(filePath);
|
||||
} else {
|
||||
audioType = getAudioFileType(content as Buffer);
|
||||
}
|
||||
|
||||
const file = await toFile(createBuffer(content as string), audioType.fileName, { type: audioType.mimeType });
|
||||
if (!file) {
|
||||
logger.error('Error converting source to file');
|
||||
throw new Error('Failed to create file for transcription');
|
||||
}
|
||||
|
||||
logger.debug(`Transcribing audio content... ${audioType.fileName} : ${audioType.mimeType}`);
|
||||
const transcription = await client.audio.transcriptions.create({
|
||||
file,
|
||||
model: 'whisper-1',
|
||||
response_format: "verbose_json",
|
||||
});
|
||||
|
||||
if (transcription && transcription.text) {
|
||||
logger.info('Successfully transcribed audio content');
|
||||
return transcription.text;
|
||||
} else {
|
||||
throw new Error('No transcription text received from OpenAI');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to transcribe audio:', (error as Error).message);
|
||||
throw new Error(`Audio transcription failed: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
export interface IHandler {
|
||||
canHandle(content: Buffer | string, isPath: boolean): Promise<boolean>;
|
||||
handle(content: Buffer | string, isPath: boolean): Promise<string>;
|
||||
}
|
||||
|
||||
export abstract class BaseHandler implements IHandler {
|
||||
abstract canHandle(content: Buffer | string, isPath: boolean): Promise<boolean>;
|
||||
abstract handle(content: Buffer | string, isPath: boolean): Promise<string>;
|
||||
}
|
||||
142
packages/osr-code-bot/src/commands/handlers/image-handler.ts
Normal file
142
packages/osr-code-bot/src/commands/handlers/image-handler.ts
Normal file
@ -0,0 +1,142 @@
|
||||
import { BaseHandler } from './base-handler'
|
||||
import * as path from 'path'
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { createClient } from '../../client'
|
||||
import { logger } from '../../index'
|
||||
import { toFile } from 'openai'
|
||||
import { IKBotOptions } from '../../zod_types'
|
||||
|
||||
// Common image file signatures/magic numbers
|
||||
const IMAGE_SIGNATURES = {
|
||||
// JPEG/JPG start with FF D8
|
||||
JPEG: new Uint8Array([0xFF, 0xD8]),
|
||||
// PNG start with 89 50 4E 47 0D 0A 1A 0A
|
||||
PNG: new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]),
|
||||
// GIF starts with either GIF87a or GIF89a
|
||||
GIF87a: new Uint8Array([0x47, 0x49, 0x46, 0x38, 0x37, 0x61]),
|
||||
GIF89a: new Uint8Array([0x47, 0x49, 0x46, 0x38, 0x39, 0x61])
|
||||
};
|
||||
|
||||
const isImageContent = (buffer: Buffer): boolean => {
|
||||
if (!buffer || buffer.length < 8) return false;
|
||||
|
||||
// Check JPEG
|
||||
if (buffer[0] === IMAGE_SIGNATURES.JPEG[0] && buffer[1] === IMAGE_SIGNATURES.JPEG[1]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check PNG
|
||||
if (IMAGE_SIGNATURES.PNG.every((byte, i) => buffer[i] === byte)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check GIF
|
||||
const isGif87a = IMAGE_SIGNATURES.GIF87a.every((byte, i) => buffer[i] === byte);
|
||||
const isGif89a = IMAGE_SIGNATURES.GIF89a.every((byte, i) => buffer[i] === byte);
|
||||
if (isGif87a || isGif89a) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getImageType = (filePath: string | Buffer): { fileName: string; mimeType: string } => {
|
||||
if (typeof filePath === 'string') {
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
switch (ext) {
|
||||
case '.jpg':
|
||||
case '.jpeg':
|
||||
return { fileName: 'image.jpg', mimeType: 'image/jpeg' };
|
||||
case '.png':
|
||||
return { fileName: 'image.png', mimeType: 'image/png' };
|
||||
case '.gif':
|
||||
return { fileName: 'image.gif', mimeType: 'image/gif' };
|
||||
}
|
||||
}
|
||||
|
||||
// Detect from content
|
||||
const buffer = Buffer.isBuffer(filePath) ? filePath : read(filePath as string);
|
||||
|
||||
if (!buffer) throw new Error('Could not read image content');
|
||||
|
||||
if (buffer[0] === IMAGE_SIGNATURES.JPEG[0] && buffer[1] === IMAGE_SIGNATURES.JPEG[1]) {
|
||||
return { fileName: 'image.jpg', mimeType: 'image/jpeg' };
|
||||
}
|
||||
if (IMAGE_SIGNATURES.PNG.every((byte, i) => buffer[i] === byte)) {
|
||||
return { fileName: 'image.png', mimeType: 'image/png' };
|
||||
}
|
||||
if (IMAGE_SIGNATURES.GIF87a.every((byte, i) => buffer[i] === byte) ||
|
||||
IMAGE_SIGNATURES.GIF89a.every((byte, i) => buffer[i] === byte)) {
|
||||
return { fileName: 'image.gif', mimeType: 'image/gif' };
|
||||
}
|
||||
|
||||
throw new Error('Unsupported image format');
|
||||
};
|
||||
|
||||
export class ImageHandler extends BaseHandler {
|
||||
private options: IKBotOptions;
|
||||
|
||||
constructor(options: IKBotOptions) {
|
||||
super();
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
async canHandle(content: Buffer | string, isPath: boolean): Promise<boolean> {
|
||||
try {
|
||||
if (isPath) {
|
||||
const ext = path.extname(content as string).toLowerCase();
|
||||
return ['.jpg', '.jpeg', '.png', '.gif'].includes(ext);
|
||||
}
|
||||
return Buffer.isBuffer(content) && isImageContent(content);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async handle(content: Buffer | string, isPath: boolean): Promise<string> {
|
||||
const client = createClient({...this.options, router: 'openai'});
|
||||
if (!client) {
|
||||
throw new Error('Failed to create OpenAI client for image analysis');
|
||||
}
|
||||
|
||||
try {
|
||||
const imageType = getImageType(content);
|
||||
const buffer = isPath ? read(content as string) : content as Buffer;
|
||||
|
||||
if (!buffer) {
|
||||
throw new Error('Failed to read image content');
|
||||
}
|
||||
|
||||
const file = await toFile(buffer as Buffer, imageType.fileName, { type: imageType.mimeType });
|
||||
if (!file) {
|
||||
throw new Error('Failed to create file for vision analysis');
|
||||
}
|
||||
|
||||
logger.debug(`Analyzing image content... ${imageType.fileName} : ${imageType.mimeType}`);
|
||||
|
||||
const response = await client.chat.completions.create({
|
||||
model: 'gpt-4-vision-preview',
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: [
|
||||
{ type: 'text', text: 'Describe this image in detail, focusing on relevant technical or content aspects:' },
|
||||
{ type: 'image_url', image_url: { url: `data:${imageType.mimeType};base64,${buffer.toString('base64')}` } }
|
||||
],
|
||||
},
|
||||
],
|
||||
max_tokens: 1500,
|
||||
});
|
||||
|
||||
if (response.choices[0]?.message?.content) {
|
||||
logger.info('Successfully analyzed image content');
|
||||
return response.choices[0].message.content;
|
||||
} else {
|
||||
throw new Error('No analysis received from OpenAI');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to analyze image:', (error as Error).message);
|
||||
throw new Error(`Image analysis failed: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
packages/osr-code-bot/src/commands/handlers/index.ts
Normal file
38
packages/osr-code-bot/src/commands/handlers/index.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { IHandler } from './base-handler'
|
||||
import { TextHandler } from './text-handler'
|
||||
import { AudioHandler } from './audio-handler'
|
||||
import { ImageHandler } from './image-handler'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import * as path from 'path'
|
||||
import { IKBotOptions } from '../../zod_types'
|
||||
|
||||
export function createHandlers(options: IKBotOptions): IHandler[] {
|
||||
return [
|
||||
new AudioHandler(options),
|
||||
new ImageHandler(options),
|
||||
new TextHandler(),
|
||||
]
|
||||
}
|
||||
|
||||
export async function detectAndHandle(content: Buffer | string, options: IKBotOptions): Promise<string> {
|
||||
const handlers = createHandlers(options)
|
||||
// Check if content is a file path
|
||||
const contentStr = content.toString();
|
||||
if (exists(contentStr)) {
|
||||
const filePath = path.resolve(contentStr);
|
||||
for (const handler of handlers) {
|
||||
if (await handler.canHandle(filePath, true)) {
|
||||
return handler.handle(filePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle as raw content
|
||||
for (const handler of handlers) {
|
||||
if (await handler.canHandle(content, false)) {
|
||||
return handler.handle(content, false);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('No suitable handler found for the input content');
|
||||
}
|
||||
33
packages/osr-code-bot/src/commands/handlers/text-handler.ts
Normal file
33
packages/osr-code-bot/src/commands/handlers/text-handler.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { BaseHandler } from './base-handler';
|
||||
import { sync as read } from '@plastichub/fs/read';
|
||||
import * as path from 'path';
|
||||
|
||||
export class TextHandler extends BaseHandler {
|
||||
async canHandle(content: Buffer | string, isPath: boolean): Promise<boolean> {
|
||||
if (isPath) {
|
||||
// For file paths, check file extension
|
||||
const ext = path.extname(content as string).toLowerCase();
|
||||
return ['.txt', '.md', '.json', '.js', '.ts'].includes(ext);
|
||||
}
|
||||
|
||||
// For raw content, try to decode as UTF-8 text
|
||||
try {
|
||||
if (Buffer.isBuffer(content)) {
|
||||
content.toString('utf8');
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async handle(content: Buffer | string, isPath: boolean): Promise<string> {
|
||||
if (isPath) {
|
||||
// Read content from file
|
||||
return read(content as string, 'string') as string;
|
||||
}
|
||||
|
||||
// Return raw content as string
|
||||
return Buffer.isBuffer(content) ? content.toString('utf8') : content;
|
||||
}
|
||||
}
|
||||
55
packages/osr-code-bot/src/commands/help.ts
Normal file
55
packages/osr-code-bot/src/commands/help.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { marked } from 'marked'
|
||||
import { markedTerminal } from 'marked-terminal'
|
||||
|
||||
import { OptionsSchema } from '../zod_schema'
|
||||
import { getDefaultValue, getDescription } from '@plastichub/osr-commons'
|
||||
import { z } from 'zod'
|
||||
|
||||
export const help = () => {
|
||||
const schema = OptionsSchema()
|
||||
const desc = schema._def.description
|
||||
const shape = schema.shape
|
||||
|
||||
const md = [
|
||||
'# KBot Command Line Interface',
|
||||
'',
|
||||
'```bash',
|
||||
'kplus modify [prompt] [options]',
|
||||
'```',
|
||||
'',
|
||||
'## Description',
|
||||
'',
|
||||
desc || 'KBot CLI Tool',
|
||||
'',
|
||||
'## Options',
|
||||
''
|
||||
]
|
||||
|
||||
// Process each parameter
|
||||
for (const [key, def] of Object.entries(shape)) {
|
||||
const isOptional = def instanceof z.ZodOptional
|
||||
|
||||
const defaultValue = getDefaultValue(def)
|
||||
const description = getDescription(def)
|
||||
|
||||
md.push(`--${key}`)
|
||||
md.push('')
|
||||
md.push(`Description: ${description}`)
|
||||
if (defaultValue !== undefined) {
|
||||
md.push(`Default: \`${JSON.stringify(defaultValue)}\``)
|
||||
}
|
||||
md.push(`Required: ${(!isOptional).toString()}`)
|
||||
md.push('')
|
||||
}
|
||||
|
||||
marked.use(markedTerminal({
|
||||
emoji: false
|
||||
}))
|
||||
const content: string = marked(md.join('\n')) as string;
|
||||
process.stdout.write(content)
|
||||
return content
|
||||
}
|
||||
|
||||
export default async (argv: any) => {
|
||||
return help()
|
||||
}
|
||||
107
packages/osr-code-bot/src/commands/init.ts
Normal file
107
packages/osr-code-bot/src/commands/init.ts
Normal file
@ -0,0 +1,107 @@
|
||||
import { sync as dir } from '@plastichub/fs/dir'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
import * as path from 'path'
|
||||
import { IKBotTask } from '../types'
|
||||
import { Logger } from 'tslog'
|
||||
import { MODULE_NAME } from '../constants'
|
||||
|
||||
const PREFERENCES_TEMPLATE = `# Personal Preferences
|
||||
|
||||
This file stores personal information and preferences to help the AI assistant provide more personalized and contextual responses.
|
||||
|
||||
## My Preferences
|
||||
|
||||
Gender :
|
||||
Location :
|
||||
Language :
|
||||
Occupation :
|
||||
Age :
|
||||
|
||||
## Contacts
|
||||
|
||||
My email address :
|
||||
My wife's email address :
|
||||
My second wife's email address :
|
||||
|
||||
## Content
|
||||
|
||||
When creating content
|
||||
|
||||
- always Markdown
|
||||
- always add links to sources
|
||||
- when searching for news, always add links to videos
|
||||
`
|
||||
|
||||
const CONFIG_TEMPLATE = {
|
||||
"deepl": {
|
||||
"auth_key": "YOUR_DEEPL_AUTH_KEY",
|
||||
"free_api": false
|
||||
},
|
||||
"scaleserp": {
|
||||
"key": "YOUR_SCALE_SERP_KEY"
|
||||
},
|
||||
"geocoder": {
|
||||
"key": "YOUR_GEOCODER_KEY"
|
||||
},
|
||||
"serpapi": {
|
||||
"key": "YOUR_SERPAPI_KEY"
|
||||
},
|
||||
"openai": {
|
||||
"key": "YOUR_OPENAI_KEY"
|
||||
},
|
||||
"bigdata": {
|
||||
"key": "YOUR_BIGDATA_KEY"
|
||||
},
|
||||
"novita": {
|
||||
"key": "YOUR_NOVITA_KEY"
|
||||
},
|
||||
"perplexity": {
|
||||
"key": "YOUR_PERPLEXITY_KEY"
|
||||
},
|
||||
"gemini": {
|
||||
"key": "YOUR_GEMINI_KEY"
|
||||
},
|
||||
"openrouter": {
|
||||
"key": "YOUR_OPENROUTER_KEY"
|
||||
},
|
||||
"deepseek": {
|
||||
"key": "YOUR_DEEPSEEK_KEY"
|
||||
},
|
||||
"google": {
|
||||
"cse": "YOUR_GOOGLE_CSE",
|
||||
"api_key": "YOUR_GOOGLE_API_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
export const init = async (argv: IKBotTask) => {
|
||||
const logger = new Logger<unknown>({
|
||||
hideLogPositionForProduction: true,
|
||||
maskPlaceholder: '***',
|
||||
name: MODULE_NAME,
|
||||
prettyLogTemplate: "{{logLevelName}}\t[{{filePathWithLine}}{{name}}]\t",
|
||||
})
|
||||
const kbotDir = path.resolve(path.join(process.cwd(), `.${MODULE_NAME}`))
|
||||
if (!exists(kbotDir)) {
|
||||
dir(kbotDir)
|
||||
}
|
||||
// Create preferences file if it doesn't exist
|
||||
const preferencesPath = path.resolve(kbotDir, 'preferences.md')
|
||||
if (!exists(preferencesPath)) {
|
||||
write(preferencesPath, PREFERENCES_TEMPLATE)
|
||||
logger.info(`📋 Created preferences file: ${preferencesPath}`)
|
||||
}else{
|
||||
logger.info(`📋 Preferences file already exists: ${preferencesPath}`)
|
||||
}
|
||||
|
||||
// Create config file if it doesn't exist
|
||||
const configPath = path.resolve(kbotDir, 'config.json')
|
||||
if (!exists(configPath)) {
|
||||
write(configPath, CONFIG_TEMPLATE)
|
||||
logger.info(`📋 Created configuration file: ${configPath}`)
|
||||
}else{
|
||||
logger.info(`📋 Configuration file already exists: ${configPath}`)
|
||||
}
|
||||
logger.info('📋 Initialization complete!')
|
||||
return 0
|
||||
}
|
||||
5
packages/osr-code-bot/src/commands/log.ts
Normal file
5
packages/osr-code-bot/src/commands/log.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import * as path from 'path'
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { Logger } from 'tslog'
|
||||
import { logger } from '../'
|
||||
75
packages/osr-code-bot/src/commands/renderer.ts
Normal file
75
packages/osr-code-bot/src/commands/renderer.ts
Normal file
@ -0,0 +1,75 @@
|
||||
// src/markdown-blessed.ts
|
||||
import * as blessed from 'blessed';
|
||||
import { marked, Tokens } from 'marked';
|
||||
|
||||
/**
|
||||
* Define a custom renderer where the `image` method
|
||||
* uses Marked's new signature: image({ href, title, text }: Tokens.Image).
|
||||
*/
|
||||
const customRenderer = {
|
||||
image({ href, title, text }: Tokens.Image): string {
|
||||
// Provide a textual placeholder instead of an actual image
|
||||
return `\n[IMAGE: ${text || 'No Alt'}](${href || 'No Href'})\n`;
|
||||
},
|
||||
// (Optional) you can override other renderer methods here
|
||||
};
|
||||
|
||||
// We tell Marked to use our custom renderer
|
||||
// Alternatively, you can pass { renderer: customRenderer } directly to marked().
|
||||
marked.use({ renderer: customRenderer });
|
||||
|
||||
/**
|
||||
* Renders the given Markdown string in a Blessed terminal UI.
|
||||
*
|
||||
* @param markdownContent - The Markdown content to display.
|
||||
*/
|
||||
export function displayMarkdown(markdownContent: string): void {
|
||||
// 1) Create Blessed screen
|
||||
const screen = blessed.screen({
|
||||
smartCSR: true,
|
||||
title: 'Markdown Example with Blessed'
|
||||
});
|
||||
|
||||
// 2) Create a scrollable box for the text
|
||||
const box = blessed.box({
|
||||
parent: screen,
|
||||
top: 'center',
|
||||
left: 'center',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
keys: true,
|
||||
vi: true,
|
||||
mouse: true,
|
||||
border: 'none',
|
||||
alwaysScroll: true,
|
||||
scrollable: true
|
||||
});
|
||||
|
||||
// 3) Parse the markdown into a string using our renderer
|
||||
const parsedContent = marked(markdownContent);
|
||||
|
||||
// 4) Set the box content
|
||||
box.setContent(parsedContent);
|
||||
|
||||
// 5) Focus and render
|
||||
box.focus();
|
||||
screen.render();
|
||||
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
const markdownSample = `
|
||||
# Hello Blessed & Marked (TypeScript)
|
||||
|
||||
Here is some **bold text**, _italic text_, and \`inline code\`.
|
||||
|
||||
Below is an image placeholder:
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
> A blockquote here to show Markdown support.
|
||||
|
||||
Enjoy!
|
||||
`;
|
||||
187
packages/osr-code-bot/src/commands/run-assistant.ts
Normal file
187
packages/osr-code-bot/src/commands/run-assistant.ts
Normal file
@ -0,0 +1,187 @@
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs'
|
||||
import OpenAI from 'openai'
|
||||
import { IKBotTask } from '../types'
|
||||
import { logger } from '../'
|
||||
import { onCompletion } from './run-completion'
|
||||
import { glob } from '../source'
|
||||
import { prompt } from '../prompt'
|
||||
import { error } from 'console'
|
||||
|
||||
const supported: Record<string, string> = {
|
||||
".c": "text/x-c",
|
||||
".cpp": "text/x-c++",
|
||||
".cs": "text/x-csharp",
|
||||
".css": "text/css",
|
||||
".doc": "application/msword",
|
||||
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
".go": "text/x-golang",
|
||||
".html": "text/html",
|
||||
".java": "text/x-java",
|
||||
".js": "text/javascript",
|
||||
".json": "application/json",
|
||||
".md": "text/markdown",
|
||||
".pdf": "application/pdf",
|
||||
".php": "text/x-php",
|
||||
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
".py": "text/x-python", // sometimes text/x-script.python
|
||||
".rb": "text/x-ruby",
|
||||
".sh": "application/x-sh",
|
||||
".tex": "text/x-tex",
|
||||
".ts": "application/typescript",
|
||||
".txt": "text/plain"
|
||||
};
|
||||
|
||||
export const createOpenAIFile = async (client: OpenAI, filePath: string, purpose: string = 'assistants') => {
|
||||
return client.files.create({
|
||||
file: fs.createReadStream(filePath),
|
||||
purpose: purpose as any
|
||||
})
|
||||
}
|
||||
/*
|
||||
class EventHandler extends EventEmitter {
|
||||
constructor(client) {
|
||||
super();
|
||||
// this.client = client;
|
||||
}
|
||||
|
||||
async onEvent(event) {
|
||||
try {
|
||||
console.log(event);
|
||||
// Retrieve events that are denoted with 'requires_action'
|
||||
// since these will have our tool_calls
|
||||
if (event.event === "thread.run.requires_action") {
|
||||
await this.handleRequiresAction(
|
||||
event.data,
|
||||
event.data.id,
|
||||
event.data.thread_id,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error handling event:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async handleRequiresAction(data, runId, threadId) {
|
||||
try {
|
||||
const toolOutputs =
|
||||
data.required_action.submit_tool_outputs.tool_calls.map((toolCall) => {
|
||||
if (toolCall.function.name === "getCurrentTemperature") {
|
||||
return {
|
||||
tool_call_id: toolCall.id,
|
||||
output: "57",
|
||||
};
|
||||
} else if (toolCall.function.name === "getRainProbability") {
|
||||
return {
|
||||
tool_call_id: toolCall.id,
|
||||
output: "0.06",
|
||||
};
|
||||
}
|
||||
});
|
||||
// Submit all the tool outputs at the same time
|
||||
await this.submitToolOutputs(toolOutputs, runId, threadId);
|
||||
} catch (error) {
|
||||
console.error("Error processing required action:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async submitToolOutputs(toolOutputs, runId, threadId) {
|
||||
try {
|
||||
// Use the submitToolOutputsStream helper
|
||||
const stream = this.client.beta.threads.runs.submitToolOutputsStream(
|
||||
threadId,
|
||||
runId,
|
||||
{ tool_outputs: toolOutputs },
|
||||
);
|
||||
for await (const event of stream) {
|
||||
this.emit("event", event);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error submitting tool outputs:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
export const runAssistant = async (client: OpenAI, params: any, options: IKBotTask) => {
|
||||
const sessionId = Date.now().toString()
|
||||
const sessionMessages = {
|
||||
sessionId,
|
||||
prompt: options.prompt,
|
||||
timestamp: new Date().toISOString(),
|
||||
messages: []
|
||||
}
|
||||
|
||||
if (options.dry) {
|
||||
logger.info('Dry run - skipping API call')
|
||||
return {
|
||||
result: 'DRY RUN',
|
||||
sessionMessages,
|
||||
result_raw: {},
|
||||
toolCalls: []
|
||||
}
|
||||
}
|
||||
const logMessage = (message: any, sessionId: string, prompt) => {
|
||||
return {
|
||||
...message,
|
||||
timestamp: new Date().toISOString(),
|
||||
sessionId,
|
||||
prompt
|
||||
}
|
||||
}
|
||||
|
||||
let result = null
|
||||
|
||||
const prompt_ = await prompt(options)
|
||||
const assistant = await client.beta.assistants.create({
|
||||
name: "Documents Assistant",
|
||||
model: params.model,
|
||||
tools: [{ type: "file_search" }, ...params.tools],
|
||||
|
||||
})
|
||||
|
||||
let files = glob(path.resolve(options.path), options.include) || []
|
||||
files = files.filter((f) => path.extname(f) in supported)
|
||||
|
||||
const attachments = await Promise.all(files.map(async (file: string) => {
|
||||
const file_id = await createOpenAIFile(client, file)
|
||||
return {
|
||||
file_id: file_id.id,
|
||||
tools: [{ type: "file_search" }]
|
||||
}
|
||||
}))
|
||||
|
||||
|
||||
const thread = await client.beta.threads.create({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: prompt_.content,
|
||||
attachments: attachments as any,
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
let defer
|
||||
try {
|
||||
defer = new Promise((resolve, reject) => {
|
||||
const stream = client.beta.threads.runs
|
||||
.stream(thread.id, {
|
||||
assistant_id: assistant.id,
|
||||
})
|
||||
//.on("textCreated", (args) => logger.trace("assistant >",args))
|
||||
.on("toolCallCreated", (event) => logger.debug("Assistant : " + event.type))
|
||||
.on("messageDone", async (event) => {
|
||||
if (event.content[0].type === "text") {
|
||||
resolve(event.content[0])
|
||||
}
|
||||
})
|
||||
return stream
|
||||
})
|
||||
} catch (e) {
|
||||
logger.error(`Failed to run assistant: ${e.message}`, error)
|
||||
}
|
||||
const ret = await defer
|
||||
return await onCompletion(ret.text.value, options)
|
||||
}
|
||||
45
packages/osr-code-bot/src/commands/run-completion.ts
Normal file
45
packages/osr-code-bot/src/commands/run-completion.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IKBotTask } from '../types'
|
||||
import OpenAI from 'openai'
|
||||
import { marked } from 'marked'
|
||||
import { markedTerminal } from 'marked-terminal'
|
||||
import * as path from 'path'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
import { resolve } from '@plastichub/osr-commons'
|
||||
import { logger } from '../'
|
||||
import { dumpAsScript } from '../utils/script'
|
||||
import { applyFilters, Filter } from '../filters'
|
||||
|
||||
export const onCompletion = async (result: any = "", options: IKBotTask) => {
|
||||
result = applyFilters(result, options.filters as Filter[] || [])
|
||||
if (options.dst) {
|
||||
const dstPath = path.resolve(resolve(options.dst, false, {
|
||||
...options.variables,
|
||||
MODEL: path.parse(options.model).name,
|
||||
ROUTER: options.router,
|
||||
}))
|
||||
write(dstPath, result)
|
||||
logger.debug(`Wrote completion result to ${dstPath}`)
|
||||
} else {
|
||||
marked.use(markedTerminal({
|
||||
emoji: false,
|
||||
}))
|
||||
const content: string = marked(result) as string;
|
||||
process.stdout.write(content)
|
||||
}
|
||||
dumpAsScript(options)
|
||||
return result
|
||||
}
|
||||
|
||||
export const runCompletion = async (client: OpenAI, params: any, options: IKBotTask) =>{
|
||||
if (options.dry) {
|
||||
logger.info('Dry run - skipping API call')
|
||||
return false
|
||||
}
|
||||
const completion = await client.chat.completions.create({
|
||||
model: options.model,
|
||||
messages: params.messages,
|
||||
})
|
||||
const result = completion.choices[0].message.content
|
||||
onCompletion(result, options)
|
||||
return result
|
||||
}
|
||||
29
packages/osr-code-bot/src/commands/run-each.ts
Normal file
29
packages/osr-code-bot/src/commands/run-each.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { globSync } from 'glob'
|
||||
import * as path from 'path'
|
||||
import { forward_slash } from '@plastichub/osr-commons'
|
||||
import { logger } from '../'
|
||||
import { IKBotTask } from '@plastichub/osr-ai-tools/types'
|
||||
|
||||
export const runEach = async (opts: IKBotTask, processRun: (args: IKBotTask) => Promise<any>) {\n const ret = []
|
||||
|
||||
if (opts.each) {
|
||||
const matches = globSync(opts.each, {
|
||||
cwd: path.resolve(opts.path),
|
||||
absolute: false
|
||||
})
|
||||
if(matches.length === 0) {
|
||||
logger.warn(`No files matching pattern ${opts.each} found in ${opts.path}`)
|
||||
return ret
|
||||
}
|
||||
logger.info(`Processing ${matches.length} files matching pattern ${opts.each}...`)
|
||||
for (const file of matches) {
|
||||
logger.info(`Processing ${file}...`)
|
||||
const fileOpts = { ...opts }
|
||||
fileOpts.include = [ forward_slash(file)]
|
||||
ret.push(await processRun(fileOpts))
|
||||
}
|
||||
} else {
|
||||
ret.push(await processRun(opts))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
66
packages/osr-code-bot/src/commands/run-tools.ts
Normal file
66
packages/osr-code-bot/src/commands/run-tools.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { IKBotTask } from '../types'
|
||||
import OpenAI from 'openai'
|
||||
import { ChatCompletionMessage, ChatCompletionMessageParam } from 'openai/resources/index.mjs'
|
||||
import { ChatCompletionToolRunnerParams } from 'openai/lib/ChatCompletionRunner'
|
||||
import { content } from '../utils/content'
|
||||
import { logger } from '../'
|
||||
import { onCompletion } from './run-completion'
|
||||
|
||||
export const runTools = async (client: OpenAI, params: any, options: IKBotTask) => {
|
||||
const sessionId = Date.now().toString()
|
||||
const sessionMessages = {
|
||||
sessionId,
|
||||
prompt: options.prompt,
|
||||
timestamp: new Date().toISOString(),
|
||||
messages: []
|
||||
}
|
||||
if (options.dry) {
|
||||
logger.info('Dry run - skipping API call')
|
||||
return {
|
||||
result: 'DRY RUN',
|
||||
sessionMessages,
|
||||
result_raw: {},
|
||||
toolCalls: []
|
||||
}
|
||||
}
|
||||
const logMessage = (message: any, sessionId: string, prompt) => {
|
||||
return {
|
||||
...message,
|
||||
timestamp: new Date().toISOString(),
|
||||
sessionId,
|
||||
prompt
|
||||
}
|
||||
}
|
||||
let runner = null
|
||||
try {
|
||||
runner = await client.beta.chat.completions.runTools(params as ChatCompletionToolRunnerParams<any>)
|
||||
.on('message', (message: ChatCompletionMessageParam) => {
|
||||
options.collector.onMessage(logMessage(message, sessionId, options.prompt))
|
||||
})
|
||||
.on('functionCall', (tool: ChatCompletionMessage.FunctionCall) => {
|
||||
return options.collector.onToolCall(logMessage(tool, sessionId, options.prompt))
|
||||
})
|
||||
.on('functionCallResult', (a) => {
|
||||
options.collector.onFunctionCallResult(a)
|
||||
})
|
||||
.on('chatCompletion', options.collector.onChatCompletion)
|
||||
.on('content', options.collector.onContent)
|
||||
} catch (e) {
|
||||
logger.trace(e)
|
||||
}
|
||||
|
||||
let result = content(runner)
|
||||
try {
|
||||
result = await runner.finalChatCompletion()
|
||||
} catch (error) {
|
||||
if (error.message.includes("(reading 'map')")) {
|
||||
logger.error('Failed to complete runner: credits :)', error.message, error.message, error)
|
||||
return
|
||||
}
|
||||
logger.error('Failed to complete runner:', error.message, error.issues)
|
||||
return
|
||||
}
|
||||
|
||||
const ret = content(result)
|
||||
return await onCompletion(ret, options)
|
||||
}
|
||||
127
packages/osr-code-bot/src/commands/run.ts
Normal file
127
packages/osr-code-bot/src/commands/run.ts
Normal file
@ -0,0 +1,127 @@
|
||||
import * as path from 'path'
|
||||
import { sync as dir } from '@plastichub/fs/dir'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { sync as write } from '@plastichub/fs/write'
|
||||
import { forward_slash, resolve } from '@plastichub/osr-commons'
|
||||
import { globSync } from 'glob'
|
||||
import { ChatCompletionToolRunnerParams } from 'openai/lib/ChatCompletionRunner'
|
||||
import { ChatCompletionMessageParam } from 'openai/resources/index.mjs'
|
||||
import { logger } from '../'
|
||||
import { createClient } from '../client'
|
||||
import { OptionsSchema } from '../zod_schema'
|
||||
import { get } from '../source'
|
||||
import { flatten } from '../utils/array'
|
||||
import { collector } from '../collector'
|
||||
import { load as loadProfile } from '../profile'
|
||||
import { load as loadTools } from '../tools'
|
||||
import { preferences, prompt } from '../prompt'
|
||||
import { variables } from '../variables'
|
||||
import { ChatCompletionType } from '../zod_schema'
|
||||
|
||||
import { runCompletion } from './run-completion'
|
||||
import { runTools } from './run-tools'
|
||||
import { runAssistant } from './run-assistant'
|
||||
import { IKBotTask } from '@plastichub/osr-ai-tools/types'
|
||||
|
||||
const processRun = async (opts: IKBotTask) => {
|
||||
|
||||
let options: IKBotTask = null
|
||||
const target = path.resolve(opts.output || opts.path)
|
||||
if (!exists(target)) {
|
||||
dir(target)
|
||||
}
|
||||
opts.disable = flatten(opts.disable)
|
||||
opts.disableTools = flatten(opts.disableTools)
|
||||
opts.include = flatten(opts.include)
|
||||
opts.variables = await loadProfile(opts)
|
||||
try {
|
||||
options = OptionsSchema().parse(opts) as any
|
||||
} catch (error) {
|
||||
logger.error('Failed to parse options:', error.message, error.issues)
|
||||
return
|
||||
}
|
||||
|
||||
const client = createClient(options)
|
||||
options.variables = { ...options.variables, ...variables(options) }
|
||||
|
||||
if (!client) {
|
||||
logger.error('Failed to create client')
|
||||
return
|
||||
}
|
||||
options.client = client
|
||||
options.collector = collector(options, client)
|
||||
|
||||
// Resolve files and messages
|
||||
let messages: Array<ChatCompletionMessageParam> = []
|
||||
let files = await get(path.resolve(options.path), options.include) || []
|
||||
files = files.map(f => { return { ...f, role: 'user' } })
|
||||
messages = [...messages as any, ...files]
|
||||
|
||||
messages.push(await prompt(opts))
|
||||
messages.push(await preferences(opts))
|
||||
|
||||
const params = {
|
||||
model: options.model,
|
||||
messages,
|
||||
tools: []
|
||||
} as ChatCompletionToolRunnerParams<any>
|
||||
|
||||
if (options.mode === ChatCompletionType.TOOLS || options.mode === ChatCompletionType.ASSISTANT) {
|
||||
params.tools = await loadTools(options)
|
||||
params.tool_choice = 'auto'
|
||||
params.parallel_tool_calls = false
|
||||
}
|
||||
|
||||
const logDir = path.resolve(resolve(opts.logs))
|
||||
const paramsPath = path.join(logDir, 'params.json')
|
||||
write(paramsPath, JSON.stringify({ ...params }, null, 2))
|
||||
logger.debug(`Read ${files.length} files from project ${path.resolve(options.path)} with ${options.include}`, files.map(f => f.path), options.variables, params.tools.map(t => `${t.function.name} : ${t.function.description}`))
|
||||
|
||||
let ret = null
|
||||
try {
|
||||
switch (options.mode) {
|
||||
case ChatCompletionType.COMPLETION:
|
||||
ret = await runCompletion(client, params, options)
|
||||
break
|
||||
|
||||
case ChatCompletionType.TOOLS:
|
||||
ret = await runTools(client, params, options)
|
||||
break
|
||||
|
||||
case ChatCompletionType.ASSISTANT:
|
||||
ret = await runAssistant(client, params, options)
|
||||
break
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported mode: ${options.mode}`)
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(`Error running ${options.mode} mode: ${e.message}`)
|
||||
}
|
||||
|
||||
opts.variables['LAST'] = ret
|
||||
return ret
|
||||
}
|
||||
|
||||
export const run = async (opts: IKBotTask) => {
|
||||
const ret = []
|
||||
if (opts.each) {
|
||||
const matches = globSync(opts.each, {
|
||||
cwd: path.resolve(opts.path),
|
||||
absolute: false
|
||||
})
|
||||
if (matches.length === 0) {
|
||||
logger.warn(`No files matching pattern ${opts.each} found in ${opts.path}`)
|
||||
return ret
|
||||
}
|
||||
logger.info(`Processing ${matches.length} files matching pattern ${opts.each}...`)
|
||||
for (const file of matches) {
|
||||
const fileOpts = { ...opts }
|
||||
fileOpts.include = [forward_slash(file)]
|
||||
ret.push(await processRun(fileOpts))
|
||||
}
|
||||
} else {
|
||||
ret.push(await processRun(opts))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
28
packages/osr-code-bot/src/config.ts
Normal file
28
packages/osr-code-bot/src/config.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import { CONFIG_DEFAULT, resolve } from '@plastichub/osr-commons'
|
||||
import { logger } from './index'
|
||||
import { sync as exists } from '@plastichub/fs/exists'
|
||||
import { sync as read } from '@plastichub/fs/read'
|
||||
import { IKBotOptions } from './zod_types'
|
||||
import { env_vars } from './utils/env'
|
||||
export const loadConfig = (options: IKBotOptions) => {
|
||||
if (options.config) {
|
||||
try {
|
||||
const configPath = path.resolve(resolve(options.config,false,env_vars()))
|
||||
if ( exists(configPath) ) {
|
||||
const parsedConfig = read(configPath,'json')
|
||||
return parsedConfig
|
||||
}else{
|
||||
logger.error(`Config file not found: ${configPath}`)
|
||||
}
|
||||
} catch (error:any) {
|
||||
logger.error(`Failed to parse config JSON: ${error.message}`)
|
||||
}
|
||||
}else{
|
||||
const config = CONFIG_DEFAULT() as any
|
||||
return config
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
packages/osr-code-bot/src/constants.ts
Normal file
11
packages/osr-code-bot/src/constants.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export const MODULE_NAME = 'kbot'
|
||||
export const EXCLUDE_GLOB = [
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/build/**",
|
||||
"**/coverage/**",
|
||||
"*.log",
|
||||
".kbot",
|
||||
".git"
|
||||
]
|
||||
export const MAX_FILE_SIZE = 1024 * 1024 * 2
|
||||
136
packages/osr-code-bot/src/filters.ts
Normal file
136
packages/osr-code-bot/src/filters.ts
Normal file
@ -0,0 +1,136 @@
|
||||
import { isString } from '@plastichub/core/primitives'
|
||||
import { logger } from './'
|
||||
|
||||
export type Filter = (json: string) => any
|
||||
|
||||
export const extractFirstCodeBlock = (markdown: string): string | null => {
|
||||
const regex = /```(\w+\n)?([\s\S]*?)```/
|
||||
const match = regex.exec(markdown)
|
||||
if (match && match[2]) {
|
||||
return match[2].trim()
|
||||
}
|
||||
return markdown
|
||||
}
|
||||
|
||||
export const extractCodeBlocks = (markdown: string): string => {
|
||||
const codeBlocks: string[] = []
|
||||
const regex = /```([\s\S]*?)```/g
|
||||
let match
|
||||
while ((match = regex.exec(markdown)) !== null) {
|
||||
codeBlocks.push(match[1])
|
||||
}
|
||||
return codeBlocks[0]
|
||||
}
|
||||
function isEscapedJsonString(input: string): boolean {
|
||||
if (typeof input !== 'string' || !input.startsWith('"') || !input.endsWith('"')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const ret = JSON.parse(input)
|
||||
return false
|
||||
} catch (error) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const unescapeJsonString = (json: string): string => {
|
||||
if (isEscapedJsonString(json)) {
|
||||
return json
|
||||
}
|
||||
// Use regex to replace common escape sequences
|
||||
const unescapedString = json
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/\\\\/g, '\\')
|
||||
.replace(/(\")/g, "\"")
|
||||
.replace(/\\b/g, '\b')
|
||||
.replace(/\\f/g, '\f')
|
||||
.replace(/\\r/g, '\r')
|
||||
.replace(/\\t/g, '\t');
|
||||
|
||||
// Handle unicode escape sequences (\uXXXX)
|
||||
return unescapedString.replace(/\\u([\d\w]{4})/gi, (match, grp) => {
|
||||
return String.fromCharCode(parseInt(grp, 16));
|
||||
});
|
||||
}
|
||||
|
||||
const alphanumericSort = (arr: string[]) => {
|
||||
arr = isString(arr) ? JSON.parse(arr) : arr
|
||||
return JSON.stringify(arr.sort((a, b) => {
|
||||
const aParts = a.match(/(\d+)|(\D+)/g) || [];
|
||||
const bParts = b.match(/(\d+)|(\D+)/g) || [];
|
||||
|
||||
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
|
||||
const aPart = aParts[i];
|
||||
const bPart = bParts[i];
|
||||
|
||||
if (isNaN(parseInt(aPart, 10)) || isNaN(parseInt(bPart, 10))) {
|
||||
// Non-numeric parts, compare as strings
|
||||
if (aPart !== bPart) {
|
||||
return aPart < bPart ? -1 : 1;
|
||||
}
|
||||
} else {
|
||||
// Numeric parts, compare as numbers
|
||||
const aNum = parseInt(aPart, 10);
|
||||
const bNum = parseInt(bPart, 10);
|
||||
if (aNum !== bNum) {
|
||||
return aNum - bNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If everything else is equal, compare by length (shorter first)
|
||||
return aParts.length - bParts.length;
|
||||
}), null, 2)
|
||||
}
|
||||
|
||||
export const JSONParse = (json: string) => {
|
||||
try {
|
||||
return JSON.parse(json)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
export const trim = (str: string) => str ? str.trim() : null
|
||||
export const extractJsonCodeBlock = (markdown: string): string | null => {
|
||||
const regex = /```json([\s\S]*?)```/g
|
||||
const match = regex.exec(markdown)
|
||||
let ret = match ? match[1] : '{}'
|
||||
try {
|
||||
return JSON.stringify(JSON.parse(ret), null, 2)
|
||||
} catch (error) {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
const JSONPretty = (json: string) => {
|
||||
return JSON.stringify(JSON.parse(json), null, 2)
|
||||
}
|
||||
|
||||
export const Filters = {
|
||||
JSON: extractJsonCodeBlock,
|
||||
JSONUnescape: unescapeJsonString,
|
||||
JSONPretty,
|
||||
AlphaSort: alphanumericSort,
|
||||
code: extractFirstCodeBlock,
|
||||
JSONParse,
|
||||
trim
|
||||
}
|
||||
|
||||
export const applyFilters = (value: string, filters: Filter[]) => {
|
||||
if (!value) {
|
||||
return ''
|
||||
}
|
||||
(filters as Filter[]).forEach((f) => {
|
||||
try {
|
||||
let _ret = f(value)
|
||||
if (_ret) {
|
||||
value = _ret
|
||||
} else {
|
||||
logger.warn(`applyFilters: filter returned null : ${value}`, f.toString())
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`Error applying filter: ${error.message}`)
|
||||
}
|
||||
})
|
||||
return value
|
||||
}
|
||||
34
packages/osr-code-bot/src/index.ts
Normal file
34
packages/osr-code-bot/src/index.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import path from 'path'
|
||||
|
||||
import { Logger } from 'tslog'
|
||||
import { createLogger } from '@plastichub/osr-log'
|
||||
import { CONFIG_DEFAULT, get_var } from '@plastichub/osr-commons'
|
||||
import { MODULE_NAME } from './constants'
|
||||
export const logger: Logger<unknown> = createLogger('llm-tools')
|
||||
export { run } from './commands/run'
|
||||
const isWindows = process.platform === 'win32'
|
||||
export const module_root = () => path.resolve(path.join(get_var( isWindows ? 'HOMEPATH' : 'HOME'), `.${MODULE_NAME}`))
|
||||
|
||||
export const assistant_supported: Record<string, string> = {
|
||||
".c": "text/x-c",
|
||||
".cpp": "text/x-c++",
|
||||
".cs": "text/x-csharp",
|
||||
".css": "text/css",
|
||||
".doc": "application/msword",
|
||||
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
".go": "text/x-golang",
|
||||
".html": "text/html",
|
||||
".java": "text/x-java",
|
||||
".js": "text/javascript",
|
||||
".json": "application/json",
|
||||
".md": "text/markdown",
|
||||
".pdf": "application/pdf",
|
||||
".php": "text/x-php",
|
||||
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
".py": "text/x-python", // sometimes text/x-script.python
|
||||
".rb": "text/x-ruby",
|
||||
".sh": "application/x-sh",
|
||||
".tex": "text/x-tex",
|
||||
".ts": "application/typescript",
|
||||
".txt": "text/plain"
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user