Compare commits

...

2 commits

Author SHA1 Message Date
igardev
33078f7e6f Add qwen3 VL 30B Instruct as a predefined model 2025-11-18 17:34:31 +02:00
igardev
b7a18c2b85 Image selection is now possible in Agent view 2025-11-18 16:14:42 +02:00
11 changed files with 736 additions and 68 deletions

535
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "llama-vscode",
"version": "0.0.34",
"version": "0.0.36",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "llama-vscode",
"version": "0.0.34",
"version": "0.0.36",
"hasInstallScript": true,
"dependencies": {
"axios": "^1.1.2",
@ -26,6 +26,7 @@
"@types/vscode": "^1.100.0",
"@vscode/test-cli": "^0.0.11",
"@vscode/test-electron": "^2.5.2",
"esbuild": "^0.27.0",
"glob": "^11.0.3",
"mocha": "^11.7.4",
"typescript": "^4.8.0",
@ -87,6 +88,448 @@
"node": ">=10.0.0"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz",
"integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz",
"integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz",
"integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz",
"integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz",
"integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz",
"integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz",
"integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz",
"integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz",
"integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz",
"integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz",
"integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz",
"integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz",
"integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz",
"integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz",
"integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz",
"integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz",
"integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz",
"integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz",
"integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz",
"integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz",
"integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz",
"integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz",
"integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz",
"integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz",
"integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz",
"integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
@ -416,9 +859,9 @@
}
},
"node_modules/@vscode/test-cli/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": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -738,6 +1181,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -786,6 +1230,7 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@ -987,6 +1432,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001669",
"electron-to-chromium": "^1.5.41",
@ -1554,6 +2000,48 @@
"node": ">= 0.4"
}
},
"node_modules/esbuild": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz",
"integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.0",
"@esbuild/android-arm": "0.27.0",
"@esbuild/android-arm64": "0.27.0",
"@esbuild/android-x64": "0.27.0",
"@esbuild/darwin-arm64": "0.27.0",
"@esbuild/darwin-x64": "0.27.0",
"@esbuild/freebsd-arm64": "0.27.0",
"@esbuild/freebsd-x64": "0.27.0",
"@esbuild/linux-arm": "0.27.0",
"@esbuild/linux-arm64": "0.27.0",
"@esbuild/linux-ia32": "0.27.0",
"@esbuild/linux-loong64": "0.27.0",
"@esbuild/linux-mips64el": "0.27.0",
"@esbuild/linux-ppc64": "0.27.0",
"@esbuild/linux-riscv64": "0.27.0",
"@esbuild/linux-s390x": "0.27.0",
"@esbuild/linux-x64": "0.27.0",
"@esbuild/netbsd-arm64": "0.27.0",
"@esbuild/netbsd-x64": "0.27.0",
"@esbuild/openbsd-arm64": "0.27.0",
"@esbuild/openbsd-x64": "0.27.0",
"@esbuild/openharmony-arm64": "0.27.0",
"@esbuild/sunos-x64": "0.27.0",
"@esbuild/win32-arm64": "0.27.0",
"@esbuild/win32-ia32": "0.27.0",
"@esbuild/win32-x64": "0.27.0"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@ -1874,15 +2362,15 @@
}
},
"node_modules/glob": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
"dev": true,
"license": "ISC",
"license": "BlueOak-1.0.0",
"dependencies": {
"foreground-child": "^3.3.1",
"jackspeak": "^4.1.1",
"minimatch": "^10.0.3",
"minimatch": "^10.1.1",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
@ -1917,11 +2405,11 @@
"license": "BSD-2-Clause"
},
"node_modules/glob/node_modules/minimatch": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dev": true,
"license": "ISC",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/brace-expansion": "^5.0.0"
},
@ -2392,9 +2880,9 @@
}
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3415,9 +3903,9 @@
}
},
"node_modules/mocha": {
"version": "11.7.4",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.4.tgz",
"integrity": "sha512-1jYAaY8x0kAZ0XszLWu14pzsf4KV740Gld4HXkhNTXwcHx4AUEDkPzgEHg9CM5dVcW+zv036tjpsEbLraPJj4w==",
"version": "11.7.5",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz",
"integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3481,9 +3969,9 @@
}
},
"node_modules/mocha/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": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"dev": true,
"license": "ISC",
"dependencies": {
@ -5029,6 +5517,7 @@
"integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.2.0",

View file

@ -342,37 +342,37 @@
"description": "The system instructions for this agent",
"default": ""
},
"toolsModel":{
"toolsModel": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name for this model to be shown to the user"
},
"endpoint": {
"type": "string",
"description": "The endpoint, from where to access the model",
"default": ""
},
"aiModel": {
"type": "string",
"description": "The name of the AI model as expected by the provider",
"default": ""
},
"isKeyRequired": {
"type": "boolean",
"description": "Is key requried for the endpoint",
"default": false
},
"localStartCommand": {
"type": "string",
"description": "Command to be used for sterting the model locally.",
"default": ""
}
},
"required": [
"name"
]
"properties": {
"name": {
"type": "string",
"description": "Name for this model to be shown to the user"
},
"endpoint": {
"type": "string",
"description": "The endpoint, from where to access the model",
"default": ""
},
"aiModel": {
"type": "string",
"description": "The name of the AI model as expected by the provider",
"default": ""
},
"isKeyRequired": {
"type": "boolean",
"description": "Is key requried for the endpoint",
"default": false
},
"localStartCommand": {
"type": "string",
"description": "Command to be used for sterting the model locally.",
"default": ""
}
},
"required": [
"name"
]
},
"tools": {
"type": "array",
@ -1998,15 +1998,15 @@
"simple-git": "^3.28.0"
},
"devDependencies": {
"@vscode/test-cli": "^0.0.11",
"@babel/types": "^7.28.4",
"@types/micromatch": "^4.0.9",
"@types/mocha": "^10.0.10",
"@types/node": "^18.0.0",
"@types/picomatch": "^4.0.0",
"@types/vscode": "^1.100.0",
"@vscode/test-cli": "^0.0.11",
"@vscode/test-electron": "^2.5.2",
"esbuild": "^0.24.0",
"esbuild": "^0.27.0",
"glob": "^11.0.3",
"mocha": "^11.7.4",
"typescript": "^4.8.0",

View file

@ -282,4 +282,11 @@ export enum OpenAiProvidersKeys {
export const OPENAI_COMP_PROVIDERS = {
[OpenAiProvidersKeys.OpenRouter]: "https://openrouter.ai/api",
[OpenAiProvidersKeys.Custom]: ""
} as const
} as const
export const SUPPORTED_IMG_FILE_EXTS: { [key: string]: string } = {
'.jpeg': 'image/jpeg',
'.jpg': 'image/jpeg',
'.png': 'image/png',
'.webp': 'image/webp'
} as const;;

View file

@ -106,11 +106,17 @@ export const PREDEFINED_LISTS = new Map<string, any>([
"aiModel": "z-ai/glm-4.5-air"
},
{
"name": "Qwen: Qwen3 235B A22B Thinking 2507 - 262.144 context $0.118/M input tokens $0.118/M output tokens (OpenRouter)",
"name": "Qwen: Qwen3 235B A22B Thinking 2507 - 262 144 context $0.118/M input tokens $0.118/M output tokens (OpenRouter)",
"endpoint": "https://openrouter.ai/api",
"isKeyRequired": true,
"aiModel": "qwen/qwen3-235b-a22b-thinking-2507"
},
{
"name": "Qwen: Qwen3 VL 30B A3B Instruct - 262 144 context $0.15/M input tokens $0.60/M output tokens (OpenRouter)",
"endpoint": "https://openrouter.ai/api",
"isKeyRequired": true,
"aiModel": "qwen/qwen3-vl-30b-a3b-instruct"
},
{
"name": "Qwen: Qwen3 Coder - 262K context $0.30/M input tokens $1.20/M output tokens (OpenRouter)",
"endpoint": "https://openrouter.ai/api",

View file

@ -5,7 +5,7 @@ import { Utils } from "./utils"
import { Chat } from "./types"
import { Plugin } from './plugin';
import * as fs from 'fs';
import { UI_TEXT_KEYS } from "./constants";
import { SUPPORTED_IMG_FILE_EXTS, UI_TEXT_KEYS } from "./constants";
interface Step {
@ -23,6 +23,8 @@ export class LlamaAgent {
private logText = ""
public contexProjectFiles: Map<string,string> = new Map();
public sentContextFiles: Map<string,string> = new Map();
public contextImage: string = "";
public sentContextImages: string[] = [];
private abortController: AbortController | null = null;
constructor(application: Application) {
@ -70,19 +72,52 @@ export class LlamaAgent {
this.logText = chat.log??"";
}
// this.app.llamaWebviewProvider.logInUi(this.logText);
this.resetContextProjectFiles();
this.resetContext();
}
resetContextProjectFiles = () => {
resetContext = () => {
this.contexProjectFiles.clear();
this.app.llamaWebviewProvider.updateContextFilesInfo();
this.sentContextFiles.clear();
this.contextImage = "";
this.sentContextImages = [];
}
addContextProjectFile = (fileLongName: string, fileShortName: string) => {
this.contexProjectFiles.set(fileLongName, fileShortName);
}
addContextProjectImage = (imagePath: string) => {
this.contextImage = imagePath;
}
removeContextProjectImage = () => {
this.contextImage = "";
}
selectImageFile = async (): Promise<string> => {
var imgPath = "";
var fileTypes = Object.values(SUPPORTED_IMG_FILE_EXTS)
fileTypes = fileTypes.map(type => type.replace("image/", ""))
const uris = await vscode.window.showOpenDialog({
canSelectMany: false,
openLabel: 'Import Model',
filters: {
'Image Files': fileTypes
},
});
if (!uris || uris.length === 0) {
return "";
}
imgPath = uris[0].fsPath;
return imgPath;
}
removeContextProjectFile = (fileLongName: string) => {
this.contexProjectFiles.delete(fileLongName);
}
@ -91,6 +126,10 @@ export class LlamaAgent {
return this.contexProjectFiles;
}
getContextProjecImage = () => {
return this.contextImage;
}
run = async (query:string, agentCommand?:string) => {
await this.askAgent(query, agentCommand);
@ -215,7 +254,8 @@ export class LlamaAgent {
streamed += delta;
this.logText += delta;
this.app.llamaWebviewProvider.logInUi(this.logText);
}, this.abortController?.signal);
}, this.abortController?.signal, !this.sentContextImages.includes(this.contextImage)? this.contextImage : "");
if (this.contextImage) this.sentContextImages.push(this.contextImage)
if (!data) {
this.logText += "No response from AI" + " \n"
this.app.llamaWebviewProvider.logInUi(this.logText);

View file

@ -5,6 +5,9 @@ import { LlmModel, LlamaChatResponse, LlamaResponse, ChatMessage } from "./types
import { Utils } from "./utils";
import * as cp from 'child_process';
import * as util from 'util';
import * as fs from 'fs';
import * as path from 'path';
import { SUPPORTED_IMG_FILE_EXTS } from "./constants";
const STATUS_OK = 200;
@ -232,9 +235,43 @@ export class LlamaServer {
};
}
private createToolsRequestPayload(messages: ChatMessage[], model: string, stream = false) {
private createToolsRequestPayload(messages: ChatMessage[], model: string, stream = false, imagePath: string = "") {
this.app.tools.addSelectedTools();
let filteredMsgs = this.filterThoughtFromMsgs(messages)
// Add image with base64 encoding
if (imagePath && fs.existsSync(imagePath)) {
var imgType = ""
for (var suffix in SUPPORTED_IMG_FILE_EXTS){
if (imagePath.endsWith(suffix)) {
imgType = SUPPORTED_IMG_FILE_EXTS[suffix];
break;
}
}
if (imgType) {
const imageBuffer = fs.readFileSync(imagePath);
const base64Image = imageBuffer.toString('base64');
const imageMessage = {
role: 'user',
content: [
{
type: 'text',
text: 'Here is an image for context:'
},
{
type: 'image_url',
image_url: {
url: `data:${imgType};base64,${base64Image}`
}
}
]
};
filteredMsgs = (filteredMsgs as any[])
filteredMsgs.push(imageMessage);
}
}
return {
"messages": filteredMsgs,
"stream": stream,
@ -343,7 +380,8 @@ export class LlamaServer {
messages: ChatMessage[],
isSummarization = false,
onDelta?: (delta: string) => void,
abortSignal?: AbortSignal
abortSignal?: AbortSignal,
imagePath = ""
): Promise<LlamaToolsResponse | undefined> => {
let selectedModel: LlmModel = this.app.getToolsModel();
let model = this.app.configuration.ai_model;
@ -379,7 +417,7 @@ export class LlamaServer {
}
// Streaming branch for tools/agent calls
request = this.createToolsRequestPayload(messages, model, true);
request = this.createToolsRequestPayload(messages, model, true, imagePath);
try {
const streamResponse = await axios.post<any>(

View file

@ -53,12 +53,16 @@ export class LlamaWebviewProvider implements vscode.WebviewViewProvider {
break;
case 'clearText':
this.app.llamaAgent.resetMessages();
this.app.llamaAgent.resetContextProjectFiles()
this.app.llamaAgent.resetContext()
await this.app.chatService.selectUpdateChat({name:"", id:""})
vscode.commands.executeCommand('llama-vscode.webview.postMessage', {
command: 'updateText',
text: ''
});
webviewView.webview.postMessage({
command: 'updateContextImage',
image: ""
});
break;
case 'showChatsHistory':
this.app.chatService.selectChatFromList();
@ -225,6 +229,30 @@ export class LlamaWebviewProvider implements vscode.WebviewViewProvider {
files: Array.from(updatedContextFiles.entries())
});
break;
case 'selectImageFile':
var selImgPath = await this.app.llamaAgent.selectImageFile();
this.app.llamaAgent.addContextProjectImage(selImgPath)
webviewView.webview.postMessage({
command: 'updateContextImage',
image: selImgPath
});
break;
case 'addContextProjectImage':
let imagePath = message.image;
this.app.llamaAgent.addContextProjectImage(imagePath);
const contextImage = this.app.llamaAgent.getContextProjecImage();
webviewView.webview.postMessage({
command: 'updateContextImage',
image: contextImage
});
break;
case 'removeContextProjectImage':
this.app.llamaAgent.removeContextProjectImage();
webviewView.webview.postMessage({
command: 'updateContextImage',
files: ""
});
break;
case 'addEditedAgentTool':
let toolsNames = message.fileLongName.split("|");
this.app.agentService.addEditedAgentTools(toolsNames[0].trim(),toolsNames[1].trim());

View file

@ -151,7 +151,6 @@ export class ModelService {
let allModels = modelsList.concat(PREDEFINED_LISTS.get(type) as LlmModel[])
let modelsItems: QuickPickItem[] = this.getModels(modelsList, "", true);
modelsItems = modelsItems.concat(this.getModels(PREDEFINED_LISTS.get(type) as LlmModel[], "(predefined) ", true, modelsList.length));
modelsItems = modelsItems.concat(this.getModels(PREDEFINED_LISTS.get(type) as LlmModel[], "(predefined) ", true, modelsList.length));
const launchToEndpoint = new Map([
["launch_completion", "endpoint"],

9
ui/package-lock.json generated
View file

@ -326,6 +326,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
"integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@ -665,6 +666,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -691,6 +693,7 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@ -917,6 +920,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001726",
"electron-to-chromium": "^1.5.173",
@ -4081,6 +4085,7 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@ -4283,6 +4288,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@ -5315,6 +5321,7 @@
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -5572,6 +5579,7 @@
"integrity": "sha512-YJB/ESPUe2Locd0NKXmw72Dx8fZQk1gTzI6rc9TAT4+Sypbnhl8jd8RywB1bDsDF9Dy1RUR7gn3q/ZJTd0OZZg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@ -5621,6 +5629,7 @@
"integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^2.1.1",

View file

@ -49,6 +49,7 @@ const App: React.FC<AppProps> = () => {
initialState.view || noViewSet
);
const [contextFiles, setContextFiles] = useState<Map<string, string>>(new Map());
const [imagePath, setContextImage] = useState<string>("");
const [agentEditTools, setAgentEditTools] = useState<Map<string, string>>(new Map());
const [agentEditDetails, setAgentEditDetails] = useState<{name:string, description:string, systemInstruction:string, toolsModel: string}>({name:"", description:"", systemInstruction:"", toolsModel:""});
@ -101,6 +102,9 @@ const App: React.FC<AppProps> = () => {
case 'updateContextFiles':
setContextFiles(new Map(message.files || []));
break;
case 'updateContextImage':
setContextImage(message.image || "");
break;
case 'updateAgentEdit':
setAgentEditDetails({name: message.name, description: message.description, systemInstruction: message.systemInstruction, toolsModel: message.toolsModel});
break;
@ -213,6 +217,8 @@ const App: React.FC<AppProps> = () => {
setCurrentState={setCurrentState}
contextFiles={contextFiles}
setContextFiles={setContextFiles}
imagePath={imagePath}
setContextImage={setContextImage}
/>
</div>
)}

View file

@ -14,6 +14,8 @@ interface AgentViewProps {
setCurrentState: (state: string) => void;
contextFiles: Map<string, string>;
setContextFiles: (files: Map<string, string>) => void;
imagePath: string;
setContextImage: (imgPath: string) => void;
}
const AgentView: React.FC<AgentViewProps> = ({
@ -26,7 +28,9 @@ const AgentView: React.FC<AgentViewProps> = ({
currentState,
setCurrentState,
contextFiles,
setContextFiles
setContextFiles,
imagePath,
setContextImage
}) => {
const [showFileSelector, setShowFileSelector] = useState<boolean>(false);
const [fileList, setFileList] = useState<string[]>([]);
@ -109,6 +113,9 @@ const AgentView: React.FC<AgentViewProps> = ({
case 'updateContextFiles':
setContextFiles(new Map(message.files || []));
break;
case 'updateContextImage':
setContextImage(message.image || "");
break;
default:
break;
}
@ -116,7 +123,7 @@ const AgentView: React.FC<AgentViewProps> = ({
window.addEventListener('message', handleMessage);
return () => window.removeEventListener('message', handleMessage);
}, [setDisplayText, setCurrentState, setContextFiles]);
}, [setDisplayText, setCurrentState, setContextFiles, setContextImage]);
// Function to focus the textarea (can be called from extension)
const focusTextarea = () => {
@ -147,6 +154,12 @@ const AgentView: React.FC<AgentViewProps> = ({
handleAddSource('getFileList');
}
const handleAddImage = () => {
vscode.postMessage({
command: 'selectImageFile'
});
}
const handleSelectToolsModel = () => {
vscode.postMessage({
command: 'selectModelWithTools'
@ -208,6 +221,10 @@ const AgentView: React.FC<AgentViewProps> = ({
command: 'addContextProjectFile',
fileLongName: fileLongName
});
// vscode.postMessage({
// command: 'addContextProjectImage',
// image: "/home/igardev/Downloads/sofia.jpeg"
// });
} else if (inputText.endsWith('/')){
vscode.postMessage({
command: 'sendAgentCommand',
@ -243,6 +260,14 @@ const AgentView: React.FC<AgentViewProps> = ({
});
};
const handleRemoveContextImage = (imagePath: string) => {
vscode.postMessage({
command: 'removeContextProjectImage',
image: imagePath
});
};
const handleOpenContextFile = (fileLongName: string) => {
vscode.postMessage({
command: 'openContextFile',
@ -403,6 +428,19 @@ const AgentView: React.FC<AgentViewProps> = ({
</div>
)}
{imagePath && (
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px' }}>
<span className="model-text">{"image: " + imagePath}</span>
<button
className="modern-btn secondary"
onClick={() => handleRemoveContextImage(imagePath)}
title="Remove image from context"
style={{ padding: '4px 8px', fontSize: '12px', minWidth: 'auto' }}
>
×
</button>
</div>
)}
{/* Modern Textarea */}
<textarea
ref={textareaRef}
@ -453,6 +491,14 @@ const AgentView: React.FC<AgentViewProps> = ({
>
@
</button>
<button
onClick={handleAddImage}
className="modern-btn secondary"
title="Add/replace image to context (.jpg, .png, .webp)"
style={{ filter: 'grayscale(100%)' }}
>
🖼
</button>
</div>
</div>
</div>