@ftarganski/omni-ai 0.1.1 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1485 -0
- package/dist/{chunk-PPTEJ2FH.js → chunk-6KQE3NUV.js} +18 -10
- package/dist/{chunk-6APAA6WD.js → chunk-A7SDO64L.js} +54 -54
- package/dist/{chunk-AWMSN7OB.js → chunk-AU3KUCI7.js} +47 -45
- package/dist/{chunk-S5MK6LBH.js → chunk-BU7KK25R.js} +33 -18
- package/dist/{chunk-6OPRALDC.js → chunk-E2JJOPZB.js} +30 -18
- package/dist/{chunk-6YFFZMXY.js → chunk-GQL6DDF4.js} +7 -4
- package/dist/{chunk-TFU437SW.js → chunk-IVDHCLGS.js} +5 -4
- package/dist/{chunk-M4QJF7CV.js → chunk-JQRNMPWC.js} +11 -6
- package/dist/{chunk-3RZELMF2.js → chunk-LEW34E32.js} +27 -18
- package/dist/{chunk-JTXDF5KG.js → chunk-MQWOX2ZJ.js} +11 -6
- package/dist/{chunk-5WELBZWN.js → chunk-WRBBQFKB.js} +10 -8
- package/dist/{chunk-Y4EYGADJ.js → chunk-YRGG3PAL.js} +15 -10
- package/dist/{chunk-AG6NZIJ3.js → chunk-ZSNUHWSC.js} +10 -10
- package/dist/cli/bin.js +297 -254
- package/dist/{src-6MUVU5ML.js → dist-KBUP5623.js} +2 -2
- package/dist/{src-ZHTGR7T6.js → dist-Z76P5KV4.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/mcp.js +15 -18
- package/dist/memory.js +27 -32
- package/dist/provider-anthropic.js +10 -10
- package/dist/provider-google.js +15 -14
- package/dist/provider-openai.js +15 -10
- package/dist/skills/backend.js +1 -1
- package/dist/skills/code.js +1 -1
- package/dist/skills/frontend.js +1 -1
- package/dist/skills/fs.js +1 -1
- package/dist/skills/git.js +1 -1
- package/dist/skills/http.js +1 -1
- package/dist/skills/index.js +9 -9
- package/dist/skills/multimodal.js +1 -1
- package/dist/skills/qa.js +1 -1
- package/dist/skills/ux.js +1 -1
- package/package.json +20 -17
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/git/git-commit-message.js
|
|
2
2
|
import { resolve } from "path";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// ../../packages/skills/dist/git/shared.js
|
|
6
6
|
import { spawn } from "child_process";
|
|
7
7
|
function runGit(args, cwd) {
|
|
8
8
|
return new Promise((resolve5, reject) => {
|
|
@@ -22,7 +22,7 @@ function runGit(args, cwd) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
//
|
|
25
|
+
// ../../packages/skills/dist/git/git-commit-message.js
|
|
26
26
|
var InputSchema = z.object({
|
|
27
27
|
cwd: z.string().default(".").describe("Repository root directory"),
|
|
28
28
|
staged: z.boolean().default(true).describe("Use staged diff (true) or full working-tree diff (false)"),
|
|
@@ -41,7 +41,8 @@ var gitCommitMessageSkill = {
|
|
|
41
41
|
const { cwd, staged, hint } = InputSchema.parse(input);
|
|
42
42
|
const dir = resolve(cwd);
|
|
43
43
|
const diffArgs = ["diff"];
|
|
44
|
-
if (staged)
|
|
44
|
+
if (staged)
|
|
45
|
+
diffArgs.push("--cached");
|
|
45
46
|
const diff = await runGit(diffArgs, dir);
|
|
46
47
|
if (!diff.trim()) {
|
|
47
48
|
return { message: "chore: no changes staged" };
|
|
@@ -57,7 +58,7 @@ var gitCommitMessageSkill = {
|
|
|
57
58
|
}
|
|
58
59
|
};
|
|
59
60
|
|
|
60
|
-
//
|
|
61
|
+
// ../../packages/skills/dist/git/git-diff.js
|
|
61
62
|
import { resolve as resolve2 } from "path";
|
|
62
63
|
import { z as z2 } from "zod";
|
|
63
64
|
var InputSchema2 = z2.object({
|
|
@@ -73,20 +74,26 @@ var gitDiffSkill = {
|
|
|
73
74
|
const { cwd, staged, file, base } = InputSchema2.parse(input);
|
|
74
75
|
const dir = resolve2(cwd);
|
|
75
76
|
const diffArgs = ["diff"];
|
|
76
|
-
if (staged)
|
|
77
|
-
|
|
78
|
-
if (
|
|
77
|
+
if (staged)
|
|
78
|
+
diffArgs.push("--cached");
|
|
79
|
+
if (base)
|
|
80
|
+
diffArgs.push(base);
|
|
81
|
+
if (file)
|
|
82
|
+
diffArgs.push("--", file);
|
|
79
83
|
const nameArgs = ["diff", "--name-only"];
|
|
80
|
-
if (staged)
|
|
81
|
-
|
|
82
|
-
if (
|
|
84
|
+
if (staged)
|
|
85
|
+
nameArgs.push("--cached");
|
|
86
|
+
if (base)
|
|
87
|
+
nameArgs.push(base);
|
|
88
|
+
if (file)
|
|
89
|
+
nameArgs.push("--", file);
|
|
83
90
|
const [diff, names] = await Promise.all([runGit(diffArgs, dir), runGit(nameArgs, dir)]);
|
|
84
91
|
const changedFiles = names.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
85
92
|
return { diff, changedFiles };
|
|
86
93
|
}
|
|
87
94
|
};
|
|
88
95
|
|
|
89
|
-
//
|
|
96
|
+
// ../../packages/skills/dist/git/git-log.js
|
|
90
97
|
import { resolve as resolve3 } from "path";
|
|
91
98
|
import { z as z3 } from "zod";
|
|
92
99
|
var InputSchema3 = z3.object({
|
|
@@ -104,8 +111,10 @@ var gitLogSkill = {
|
|
|
104
111
|
const { cwd, maxEntries, branch, since } = InputSchema3.parse(input);
|
|
105
112
|
const dir = resolve3(cwd);
|
|
106
113
|
const args = ["log", `--format=${FORMAT}`, `-n`, String(maxEntries)];
|
|
107
|
-
if (since)
|
|
108
|
-
|
|
114
|
+
if (since)
|
|
115
|
+
args.push(`--since=${since}`);
|
|
116
|
+
if (branch)
|
|
117
|
+
args.push(branch);
|
|
109
118
|
const raw = await runGit(args, dir);
|
|
110
119
|
const commits = raw.split("\n").filter(Boolean).map((line) => {
|
|
111
120
|
const [hash, shortHash, author, date, ...rest] = line.split(SEP);
|
|
@@ -115,7 +124,7 @@ var gitLogSkill = {
|
|
|
115
124
|
}
|
|
116
125
|
};
|
|
117
126
|
|
|
118
|
-
//
|
|
127
|
+
// ../../packages/skills/dist/git/git-status.js
|
|
119
128
|
import { resolve as resolve4 } from "path";
|
|
120
129
|
import { z as z4 } from "zod";
|
|
121
130
|
var InputSchema4 = z4.object({
|
|
@@ -126,15 +135,18 @@ function parsePorcelain(raw) {
|
|
|
126
135
|
const unstaged = [];
|
|
127
136
|
const untracked = [];
|
|
128
137
|
for (const line of raw.split("\n")) {
|
|
129
|
-
if (!line || line.startsWith("##"))
|
|
138
|
+
if (!line || line.startsWith("##"))
|
|
139
|
+
continue;
|
|
130
140
|
const x = line[0];
|
|
131
141
|
const y = line[1];
|
|
132
142
|
const path = line.slice(3);
|
|
133
143
|
if (x === "?" && y === "?") {
|
|
134
144
|
untracked.push(path);
|
|
135
145
|
} else {
|
|
136
|
-
if (x !== " " && x !== "?")
|
|
137
|
-
|
|
146
|
+
if (x !== " " && x !== "?")
|
|
147
|
+
staged.push({ path, status: x });
|
|
148
|
+
if (y !== " " && y !== "?")
|
|
149
|
+
unstaged.push({ path, status: y });
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
return { staged, unstaged, untracked };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/http/http-request.js
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
var BearerAuthSchema = z.object({
|
|
4
4
|
type: z.literal("bearer"),
|
|
@@ -26,7 +26,8 @@ var InputSchema = z.object({
|
|
|
26
26
|
timeoutMs: z.number().int().positive().default(3e4).describe("Request timeout in milliseconds")
|
|
27
27
|
});
|
|
28
28
|
async function resolveToken(auth) {
|
|
29
|
-
if (auth.type === "bearer")
|
|
29
|
+
if (auth.type === "bearer")
|
|
30
|
+
return `Bearer ${auth.token}`;
|
|
30
31
|
if (auth.type === "basic") {
|
|
31
32
|
const encoded = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
|
|
32
33
|
return `Basic ${encoded}`;
|
|
@@ -36,7 +37,8 @@ async function resolveToken(auth) {
|
|
|
36
37
|
client_id: auth.clientId,
|
|
37
38
|
client_secret: auth.clientSecret
|
|
38
39
|
});
|
|
39
|
-
if (auth.scope)
|
|
40
|
+
if (auth.scope)
|
|
41
|
+
params.set("scope", auth.scope);
|
|
40
42
|
const tokenRes = await fetch(auth.tokenUrl, {
|
|
41
43
|
method: "POST",
|
|
42
44
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
@@ -46,7 +48,8 @@ async function resolveToken(auth) {
|
|
|
46
48
|
throw new Error(`OAuth2 token request failed: ${tokenRes.status} ${tokenRes.statusText}`);
|
|
47
49
|
}
|
|
48
50
|
const json = await tokenRes.json();
|
|
49
|
-
if (!json.access_token)
|
|
51
|
+
if (!json.access_token)
|
|
52
|
+
throw new Error("OAuth2 response did not include access_token");
|
|
50
53
|
const tokenType = json.token_type ?? "Bearer";
|
|
51
54
|
return `${tokenType} ${json.access_token}`;
|
|
52
55
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/fs/list-directory.js
|
|
2
2
|
import { readdir } from "fs/promises";
|
|
3
3
|
import { join, resolve, sep } from "path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -27,7 +27,8 @@ async function walk(dir, recursive, extensions) {
|
|
|
27
27
|
}
|
|
28
28
|
} else if (entry.isFile()) {
|
|
29
29
|
const include = !extensions || extensions.some((ext) => entry.name.endsWith(ext));
|
|
30
|
-
if (include)
|
|
30
|
+
if (include)
|
|
31
|
+
results.push(fullPath);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
return results;
|
|
@@ -42,7 +43,7 @@ var listDirectorySkill = {
|
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
45
|
|
|
45
|
-
//
|
|
46
|
+
// ../../packages/skills/dist/fs/read-file.js
|
|
46
47
|
import { readFile } from "fs/promises";
|
|
47
48
|
import { resolve as resolve2, sep as sep2 } from "path";
|
|
48
49
|
import { z as z2 } from "zod";
|
|
@@ -68,7 +69,7 @@ var readFileSkill = {
|
|
|
68
69
|
}
|
|
69
70
|
};
|
|
70
71
|
|
|
71
|
-
//
|
|
72
|
+
// ../../packages/skills/dist/fs/write-file.js
|
|
72
73
|
import { mkdir, writeFile } from "fs/promises";
|
|
73
74
|
import { dirname, resolve as resolve3, sep as sep3 } from "path";
|
|
74
75
|
import { z as z3 } from "zod";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/code/search-code.js
|
|
2
2
|
import { readdir, readFile } from "fs/promises";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -10,22 +10,27 @@ var InputSchema = z.object({
|
|
|
10
10
|
useRegex: z.boolean().default(false).describe("Treat pattern as a regular expression")
|
|
11
11
|
});
|
|
12
12
|
async function searchInFile(filePath, matcher, results, maxResults) {
|
|
13
|
-
if (results.length >= maxResults)
|
|
13
|
+
if (results.length >= maxResults)
|
|
14
|
+
return;
|
|
14
15
|
const text = await readFile(filePath, "utf-8");
|
|
15
16
|
const lines = text.split("\n");
|
|
16
17
|
for (let i = 0; i < lines.length; i++) {
|
|
17
|
-
if (results.length >= maxResults)
|
|
18
|
+
if (results.length >= maxResults)
|
|
19
|
+
break;
|
|
18
20
|
if (matcher(lines[i])) {
|
|
19
21
|
results.push({ file: filePath, line: i + 1, content: lines[i].trim() });
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
async function walkAndSearch(dir, extensions, matcher, results, maxResults) {
|
|
24
|
-
if (results.length >= maxResults)
|
|
26
|
+
if (results.length >= maxResults)
|
|
27
|
+
return;
|
|
25
28
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
26
29
|
for (const entry of entries) {
|
|
27
|
-
if (results.length >= maxResults)
|
|
28
|
-
|
|
30
|
+
if (results.length >= maxResults)
|
|
31
|
+
break;
|
|
32
|
+
if (entry.name === "node_modules" || entry.name === "dist")
|
|
33
|
+
continue;
|
|
29
34
|
const fullPath = join(dir, entry.name);
|
|
30
35
|
if (entry.isDirectory()) {
|
|
31
36
|
await walkAndSearch(fullPath, extensions, matcher, results, maxResults);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/backend/analyze-dynamo-schema.js
|
|
2
2
|
import { readFile } from "fs/promises";
|
|
3
3
|
import { resolve } from "path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -15,13 +15,16 @@ function extractEntityType(source) {
|
|
|
15
15
|
}
|
|
16
16
|
function extractFields(source) {
|
|
17
17
|
const fieldsKeyIdx = source.indexOf("fields:");
|
|
18
|
-
if (fieldsKeyIdx === -1)
|
|
18
|
+
if (fieldsKeyIdx === -1)
|
|
19
|
+
return [];
|
|
19
20
|
const braceOpen = source.indexOf("{", fieldsKeyIdx);
|
|
20
|
-
if (braceOpen === -1)
|
|
21
|
+
if (braceOpen === -1)
|
|
22
|
+
return [];
|
|
21
23
|
let depth = 0;
|
|
22
24
|
let fieldsEnd = -1;
|
|
23
25
|
for (let i = braceOpen; i < source.length; i++) {
|
|
24
|
-
if (source[i] === "{")
|
|
26
|
+
if (source[i] === "{")
|
|
27
|
+
depth++;
|
|
25
28
|
else if (source[i] === "}") {
|
|
26
29
|
depth--;
|
|
27
30
|
if (depth === 0) {
|
|
@@ -30,7 +33,8 @@ function extractFields(source) {
|
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
|
-
if (fieldsEnd === -1)
|
|
36
|
+
if (fieldsEnd === -1)
|
|
37
|
+
return [];
|
|
34
38
|
const fieldsBlock = source.slice(braceOpen + 1, fieldsEnd);
|
|
35
39
|
const fields = [];
|
|
36
40
|
for (const m of fieldsBlock.matchAll(/(\w+)\s*:\s*\{([^}]*)\}/g)) {
|
|
@@ -74,7 +78,7 @@ var analyzeDynamoSchemaSkill = {
|
|
|
74
78
|
}
|
|
75
79
|
};
|
|
76
80
|
|
|
77
|
-
//
|
|
81
|
+
// ../../packages/skills/dist/backend/analyze-graphql-schema.js
|
|
78
82
|
import { readFile as readFile2 } from "fs/promises";
|
|
79
83
|
import { resolve as resolve2 } from "path";
|
|
80
84
|
import { z as z2 } from "zod";
|
|
@@ -84,7 +88,8 @@ var InputSchema2 = z2.object({
|
|
|
84
88
|
function extractOperations(source, section) {
|
|
85
89
|
const sectionRe = new RegExp(`extend\\s+type\\s+${section}\\s*\\{([^}]*)\\}`, "s");
|
|
86
90
|
const match = sectionRe.exec(source);
|
|
87
|
-
if (!match)
|
|
91
|
+
if (!match)
|
|
92
|
+
return [];
|
|
88
93
|
const ops = [];
|
|
89
94
|
for (const m of match[1].matchAll(/(\w+)\s*(\([^)]*\))?\s*:\s*([^\n@#]+)((?:\s*@\w+[^\n]*)*)/g)) {
|
|
90
95
|
const directives = m[4].trim().split(/\s*@/).filter(Boolean).map((d) => `@${d.trim()}`);
|
|
@@ -100,7 +105,8 @@ function extractOperations(source, section) {
|
|
|
100
105
|
function extractTypes(source) {
|
|
101
106
|
const types = [];
|
|
102
107
|
for (const m of source.matchAll(/(?:^|\n)\s*(?:extend\s+)?type\s+(\w+)\s*(?:implements[^{]*)?\{/g)) {
|
|
103
|
-
if (!["Query", "Mutation", "Subscription"].includes(m[1]))
|
|
108
|
+
if (!["Query", "Mutation", "Subscription"].includes(m[1]))
|
|
109
|
+
types.push(m[1]);
|
|
104
110
|
}
|
|
105
111
|
return [...new Set(types)];
|
|
106
112
|
}
|
|
@@ -126,7 +132,7 @@ var analyzeGraphqlSchemaSkill = {
|
|
|
126
132
|
}
|
|
127
133
|
};
|
|
128
134
|
|
|
129
|
-
//
|
|
135
|
+
// ../../packages/skills/dist/backend/analyze-nestjs-module.js
|
|
130
136
|
import { readFile as readFile3 } from "fs/promises";
|
|
131
137
|
import { resolve as resolve3 } from "path";
|
|
132
138
|
import { z as z3 } from "zod";
|
|
@@ -136,10 +142,9 @@ var InputSchema3 = z3.object({
|
|
|
136
142
|
function extractArrayItems(source, key) {
|
|
137
143
|
const re = new RegExp(`${key}\\s*:\\s*\\[([^\\]]*?)\\]`, "s");
|
|
138
144
|
const match = re.exec(source);
|
|
139
|
-
if (!match)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
).filter(Boolean);
|
|
145
|
+
if (!match)
|
|
146
|
+
return [];
|
|
147
|
+
return match[1].split(",").map((s) => s.trim().replace(/\/\/.*$/m, "").trim()).filter(Boolean);
|
|
143
148
|
}
|
|
144
149
|
function extractModuleName(source) {
|
|
145
150
|
const match = /export\s+class\s+(\w+Module)/.exec(source);
|
|
@@ -161,7 +166,7 @@ var analyzeNestjsModuleSkill = {
|
|
|
161
166
|
}
|
|
162
167
|
};
|
|
163
168
|
|
|
164
|
-
//
|
|
169
|
+
// ../../packages/skills/dist/backend/find-code-pattern.js
|
|
165
170
|
import { readdir, readFile as readFile4 } from "fs/promises";
|
|
166
171
|
import { join } from "path";
|
|
167
172
|
import { z as z4 } from "zod";
|
|
@@ -179,12 +184,16 @@ var InputSchema4 = z4.object({
|
|
|
179
184
|
maxExamples: z4.number().int().positive().default(3).describe("Maximum number of examples to return")
|
|
180
185
|
});
|
|
181
186
|
async function walkForPattern(dir, suffixes, results, max) {
|
|
182
|
-
if (results.length >= max)
|
|
187
|
+
if (results.length >= max)
|
|
188
|
+
return;
|
|
183
189
|
const entries = await readdir(dir, { withFileTypes: true }).catch(() => null);
|
|
184
|
-
if (!entries)
|
|
190
|
+
if (!entries)
|
|
191
|
+
return;
|
|
185
192
|
for (const entry of entries) {
|
|
186
|
-
if (results.length >= max)
|
|
187
|
-
|
|
193
|
+
if (results.length >= max)
|
|
194
|
+
break;
|
|
195
|
+
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
|
|
196
|
+
continue;
|
|
188
197
|
const fullPath = join(dir, entry.name);
|
|
189
198
|
if (entry.isDirectory()) {
|
|
190
199
|
await walkForPattern(fullPath, suffixes, results, max);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/ux/audit-accessibility.js
|
|
2
2
|
import { readdir, readFile } from "fs/promises";
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -87,9 +87,11 @@ async function auditFile(filePath) {
|
|
|
87
87
|
for (const rule of RULES) {
|
|
88
88
|
rule.pattern.lastIndex = 0;
|
|
89
89
|
const match = rule.pattern.exec(line);
|
|
90
|
-
if (!match)
|
|
90
|
+
if (!match)
|
|
91
|
+
continue;
|
|
91
92
|
const isIssue = rule.isIssue ? rule.isIssue(match, line, lines, i) : true;
|
|
92
|
-
if (!isIssue)
|
|
93
|
+
if (!isIssue)
|
|
94
|
+
continue;
|
|
93
95
|
issues.push({
|
|
94
96
|
file: filePath,
|
|
95
97
|
line: i + 1,
|
|
@@ -106,11 +108,14 @@ async function auditFile(filePath) {
|
|
|
106
108
|
var MAX_DEPTH = 10;
|
|
107
109
|
var MAX_FILES = 500;
|
|
108
110
|
async function collectFiles(dir, recursive, depth = 0, results = []) {
|
|
109
|
-
if (depth > MAX_DEPTH || results.length >= MAX_FILES)
|
|
111
|
+
if (depth > MAX_DEPTH || results.length >= MAX_FILES)
|
|
112
|
+
return results;
|
|
110
113
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
111
114
|
for (const entry of entries) {
|
|
112
|
-
if (results.length >= MAX_FILES)
|
|
113
|
-
|
|
115
|
+
if (results.length >= MAX_FILES)
|
|
116
|
+
break;
|
|
117
|
+
if (entry.name === "node_modules" || entry.name === "dist")
|
|
118
|
+
continue;
|
|
114
119
|
const full = join(dir, entry.name);
|
|
115
120
|
if (entry.isDirectory() && recursive) {
|
|
116
121
|
await collectFiles(full, recursive, depth + 1, results);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/skills/dist/multimodal/analyze-image.js
|
|
2
2
|
import { readFile } from "fs/promises";
|
|
3
3
|
import { extname } from "path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -23,21 +23,25 @@ async function loadImage(input) {
|
|
|
23
23
|
if (input.imagePath) {
|
|
24
24
|
const ext = extname(input.imagePath).toLowerCase();
|
|
25
25
|
const mimeType2 = input.mimeType ?? EXT_TO_MIME[ext];
|
|
26
|
-
if (!mimeType2)
|
|
26
|
+
if (!mimeType2)
|
|
27
|
+
throw new Error(`Unsupported image extension "${ext}". Use: ${Object.keys(EXT_TO_MIME).join(", ")}`);
|
|
27
28
|
const data = (await readFile(input.imagePath)).toString("base64");
|
|
28
29
|
return { data, mimeType: mimeType2 };
|
|
29
30
|
}
|
|
30
31
|
if (input.imageUrl) {
|
|
31
32
|
const res = await fetch(input.imageUrl);
|
|
32
|
-
if (!res.ok)
|
|
33
|
+
if (!res.ok)
|
|
34
|
+
throw new Error(`Failed to fetch image: ${res.status} ${res.statusText}`);
|
|
33
35
|
const contentType = res.headers.get("content-type") ?? "";
|
|
34
36
|
const mimeType2 = input.mimeType ?? SUPPORTED_MIME.find((m) => contentType.startsWith(m));
|
|
35
|
-
if (!mimeType2)
|
|
37
|
+
if (!mimeType2)
|
|
38
|
+
throw new Error(`Unsupported content-type "${contentType}"`);
|
|
36
39
|
const buffer = await res.arrayBuffer();
|
|
37
40
|
return { data: Buffer.from(buffer).toString("base64"), mimeType: mimeType2 };
|
|
38
41
|
}
|
|
39
42
|
const mimeType = input.mimeType;
|
|
40
|
-
if (!mimeType)
|
|
43
|
+
if (!mimeType)
|
|
44
|
+
throw new Error("mimeType is required when supplying imageBase64");
|
|
41
45
|
return { data: input.imageBase64, mimeType };
|
|
42
46
|
}
|
|
43
47
|
var analyzeImageSkill = {
|
|
@@ -46,9 +50,7 @@ var analyzeImageSkill = {
|
|
|
46
50
|
async execute(input, ctx) {
|
|
47
51
|
const parsed = InputSchema.parse(input);
|
|
48
52
|
if (!ctx.provider.capabilities.vision) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
`Provider "${ctx.provider.name}" does not support vision. Configure a vision-capable provider (e.g. Anthropic claude-3, OpenAI gpt-4o).`
|
|
51
|
-
);
|
|
53
|
+
throw new Error(`Provider "${ctx.provider.name}" does not support vision. Configure a vision-capable provider (e.g. Anthropic claude-3, OpenAI gpt-4o).`);
|
|
52
54
|
}
|
|
53
55
|
const { data, mimeType } = await loadImage(parsed);
|
|
54
56
|
const imagePart = { type: "image", mimeType, data };
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
registerProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AU3KUCI7.js";
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// ../../packages/provider-openai/dist/provider.js
|
|
7
7
|
import OpenAI from "openai";
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// ../../packages/provider-openai/dist/mappers.js
|
|
10
10
|
function toOpenAIUserContentPart(part) {
|
|
11
|
-
if (part.type === "text")
|
|
11
|
+
if (part.type === "text")
|
|
12
|
+
return { type: "text", text: part.text };
|
|
12
13
|
return {
|
|
13
14
|
type: "image_url",
|
|
14
15
|
image_url: { url: `data:${part.mimeType};base64,${part.data}` }
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
function contentAsString(content) {
|
|
18
|
-
if (typeof content === "string")
|
|
19
|
+
if (typeof content === "string")
|
|
20
|
+
return content;
|
|
19
21
|
return content.map((p) => p.type === "text" ? p.text : "").join("");
|
|
20
22
|
}
|
|
21
23
|
function toOpenAIMessages(messages) {
|
|
@@ -65,7 +67,7 @@ function fromOpenAIResponse(response, providerName) {
|
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
//
|
|
70
|
+
// ../../packages/provider-openai/dist/provider.js
|
|
69
71
|
var OpenAIProvider = class {
|
|
70
72
|
name;
|
|
71
73
|
capabilities = {
|
|
@@ -116,9 +118,12 @@ var OpenAIProvider = class {
|
|
|
116
118
|
if (!toolCallAccum[idx]) {
|
|
117
119
|
toolCallAccum[idx] = { id: "", name: "", args: "" };
|
|
118
120
|
}
|
|
119
|
-
if (tc.id)
|
|
120
|
-
|
|
121
|
-
if (tc.function?.
|
|
121
|
+
if (tc.id)
|
|
122
|
+
toolCallAccum[idx].id = tc.id;
|
|
123
|
+
if (tc.function?.name)
|
|
124
|
+
toolCallAccum[idx].name = tc.function.name;
|
|
125
|
+
if (tc.function?.arguments)
|
|
126
|
+
toolCallAccum[idx].args += tc.function.arguments;
|
|
122
127
|
}
|
|
123
128
|
}
|
|
124
129
|
if (chunk.usage) {
|
|
@@ -167,7 +172,7 @@ var OpenAIProvider = class {
|
|
|
167
172
|
}
|
|
168
173
|
};
|
|
169
174
|
|
|
170
|
-
//
|
|
175
|
+
// ../../packages/provider-openai/dist/index.js
|
|
171
176
|
registerProvider("openai", (config) => {
|
|
172
177
|
if (!config.apiKey) {
|
|
173
178
|
throw new Error(`Provider "${config.name}" (openai) requires OPENAI_API_KEY to be set in the environment.`);
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
registerProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AU3KUCI7.js";
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// ../../packages/provider-anthropic/dist/provider.js
|
|
7
7
|
import Anthropic from "@anthropic-ai/sdk";
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// ../../packages/provider-anthropic/dist/mappers.js
|
|
10
10
|
function toAnthropicContentPart(part) {
|
|
11
|
-
if (part.type === "text")
|
|
11
|
+
if (part.type === "text")
|
|
12
|
+
return { type: "text", text: part.text };
|
|
12
13
|
return {
|
|
13
14
|
type: "image",
|
|
14
15
|
source: { type: "base64", media_type: part.mimeType, data: part.data }
|
|
@@ -30,7 +31,8 @@ function toAnthropicTools(tools) {
|
|
|
30
31
|
function extractSystemPrompt(request) {
|
|
31
32
|
const systemMsg = request.messages.find((m) => m.role === "system");
|
|
32
33
|
const raw = request.systemPrompt ?? systemMsg?.content;
|
|
33
|
-
if (raw === void 0)
|
|
34
|
+
if (raw === void 0)
|
|
35
|
+
return void 0;
|
|
34
36
|
return typeof raw === "string" ? raw : raw.map((p) => p.type === "text" ? p.text : "").join("");
|
|
35
37
|
}
|
|
36
38
|
function fromAnthropicResponse(response, providerName) {
|
|
@@ -59,7 +61,7 @@ function fromAnthropicResponse(response, providerName) {
|
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
//
|
|
64
|
+
// ../../packages/provider-anthropic/dist/provider.js
|
|
63
65
|
var AnthropicProvider = class {
|
|
64
66
|
name;
|
|
65
67
|
capabilities = {
|
|
@@ -79,9 +81,7 @@ var AnthropicProvider = class {
|
|
|
79
81
|
async complete(request) {
|
|
80
82
|
const model = request.model ?? this.defaultModel;
|
|
81
83
|
if (request.temperature !== void 0 && request.temperature > 1) {
|
|
82
|
-
throw new Error(
|
|
83
|
-
`Anthropic models require temperature <= 1.0 (got ${request.temperature}). Update the agent YAML or use an OpenAI provider for higher temperature values.`
|
|
84
|
-
);
|
|
84
|
+
throw new Error(`Anthropic models require temperature <= 1.0 (got ${request.temperature}). Update the agent YAML or use an OpenAI provider for higher temperature values.`);
|
|
85
85
|
}
|
|
86
86
|
const system = extractSystemPrompt(request);
|
|
87
87
|
const messages = toAnthropicMessages(request.messages);
|
|
@@ -105,7 +105,7 @@ var AnthropicProvider = class {
|
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
//
|
|
108
|
+
// ../../packages/provider-anthropic/dist/index.js
|
|
109
109
|
registerProvider("anthropic", (config) => {
|
|
110
110
|
if (!config.apiKey) {
|
|
111
111
|
throw new Error(`Provider "${config.name}" (anthropic) requires ANTHROPIC_API_KEY to be set in the environment.`);
|