@kernel.chat/kbot 3.99.31 → 3.99.33
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 +1 -1
- package/dist/agents/security-agent.d.ts +31 -0
- package/dist/agents/security-agent.js +180 -0
- package/dist/agents/security-rules.d.ts +35 -0
- package/dist/agents/security-rules.js +206 -0
- package/dist/agents/specialists.d.ts +6 -0
- package/dist/agents/specialists.js +45 -0
- package/dist/architect.js +5 -0
- package/dist/auth.js +1 -1
- package/dist/channels/matrix.d.ts +4 -0
- package/dist/channels/matrix.js +28 -0
- package/dist/channels/office.d.ts +78 -0
- package/dist/channels/office.js +169 -0
- package/dist/channels/registry.d.ts +8 -0
- package/dist/channels/registry.js +38 -0
- package/dist/channels/signal.d.ts +4 -0
- package/dist/channels/signal.js +29 -0
- package/dist/channels/slack.d.ts +4 -0
- package/dist/channels/slack.js +97 -0
- package/dist/channels/teams.d.ts +4 -0
- package/dist/channels/teams.js +29 -0
- package/dist/channels/telegram.d.ts +4 -0
- package/dist/channels/telegram.js +28 -0
- package/dist/channels/types.d.ts +50 -0
- package/dist/channels/types.js +13 -0
- package/dist/channels/whatsapp.d.ts +4 -0
- package/dist/channels/whatsapp.js +28 -0
- package/dist/computer-use-coordinator.d.ts +44 -0
- package/dist/computer-use-coordinator.js +0 -0
- package/dist/file-library.d.ts +76 -0
- package/dist/file-library.js +269 -0
- package/dist/managed-agents-anthropic.d.ts +90 -0
- package/dist/managed-agents-anthropic.js +123 -0
- package/dist/plugins-integrity.d.ts +72 -0
- package/dist/plugins-integrity.js +153 -0
- package/dist/plugins.d.ts +13 -2
- package/dist/plugins.js +87 -10
- package/dist/tools/anthropic-managed-agents-tools.d.ts +22 -0
- package/dist/tools/anthropic-managed-agents-tools.js +191 -0
- package/dist/tools/channel-tools.d.ts +4 -0
- package/dist/tools/channel-tools.js +80 -0
- package/dist/tools/computer-coordinator-tools.d.ts +13 -0
- package/dist/tools/computer-coordinator-tools.js +104 -0
- package/dist/tools/computer.js +463 -299
- package/dist/tools/file-library-tools.d.ts +12 -0
- package/dist/tools/file-library-tools.js +191 -0
- package/dist/tools/image-thoughtful.d.ts +31 -0
- package/dist/tools/image-thoughtful.js +233 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/security-agent-tools.d.ts +34 -0
- package/dist/tools/security-agent-tools.js +30 -0
- package/dist/tools/swarm-2026-04.d.ts +2 -0
- package/dist/tools/swarm-2026-04.js +91 -0
- package/dist/tools/workspace-agent-tools.d.ts +19 -0
- package/dist/tools/workspace-agent-tools.js +191 -0
- package/dist/workspace-agents.d.ts +132 -0
- package/dist/workspace-agents.js +379 -0
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Library tool definitions.
|
|
3
|
+
*
|
|
4
|
+
* These mirror ChatGPT's File Library surface: add, list, search, get.
|
|
5
|
+
* Definitions only — NOT registered here. Wire-up belongs in tools/index.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolDefinition } from "./index.js";
|
|
8
|
+
export declare const fileLibraryAddTool: ToolDefinition;
|
|
9
|
+
export declare const fileLibraryListTool: ToolDefinition;
|
|
10
|
+
export declare const fileLibrarySearchTool: ToolDefinition;
|
|
11
|
+
export declare const fileLibraryGetTool: ToolDefinition;
|
|
12
|
+
//# sourceMappingURL=file-library-tools.d.ts.map
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Library tool definitions.
|
|
3
|
+
*
|
|
4
|
+
* These mirror ChatGPT's File Library surface: add, list, search, get.
|
|
5
|
+
* Definitions only — NOT registered here. Wire-up belongs in tools/index.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { getDefaultFileLibrary, } from "../file-library.js";
|
|
8
|
+
const VALID_SOURCES = [
|
|
9
|
+
"user-upload",
|
|
10
|
+
"agent-output",
|
|
11
|
+
"tool-output",
|
|
12
|
+
];
|
|
13
|
+
function lib() {
|
|
14
|
+
return getDefaultFileLibrary();
|
|
15
|
+
}
|
|
16
|
+
function asString(v) {
|
|
17
|
+
return v === undefined || v === null ? "" : String(v);
|
|
18
|
+
}
|
|
19
|
+
function fmtEntry(e) {
|
|
20
|
+
return {
|
|
21
|
+
id: e.id,
|
|
22
|
+
name: e.name,
|
|
23
|
+
mimeType: e.mimeType,
|
|
24
|
+
size: e.size,
|
|
25
|
+
createdAt: e.createdAt,
|
|
26
|
+
source: e.source,
|
|
27
|
+
tags: e.tags,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export const fileLibraryAddTool = {
|
|
31
|
+
name: "file_library_add",
|
|
32
|
+
description: "Save a file into the local File Library. Provide content (utf8 string) or base64-encoded bytes. Returns the new entry id and metadata.",
|
|
33
|
+
tier: "free",
|
|
34
|
+
parameters: {
|
|
35
|
+
name: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "File name (e.g. 'report.md')",
|
|
38
|
+
required: true,
|
|
39
|
+
},
|
|
40
|
+
mimeType: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "MIME type (e.g. 'text/markdown', 'application/pdf')",
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
source: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Origin: 'user-upload' | 'agent-output' | 'tool-output'",
|
|
48
|
+
required: true,
|
|
49
|
+
},
|
|
50
|
+
content: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "UTF-8 text content. Omit if using contentBase64.",
|
|
53
|
+
},
|
|
54
|
+
contentBase64: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "Base64-encoded bytes. Omit if using content.",
|
|
57
|
+
},
|
|
58
|
+
tags: {
|
|
59
|
+
type: "array",
|
|
60
|
+
description: "Optional tags",
|
|
61
|
+
items: { type: "string" },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
async execute(args) {
|
|
65
|
+
const name = asString(args.name);
|
|
66
|
+
const mimeType = asString(args.mimeType);
|
|
67
|
+
const sourceRaw = asString(args.source);
|
|
68
|
+
if (!VALID_SOURCES.includes(sourceRaw)) {
|
|
69
|
+
return `Error: source must be one of ${VALID_SOURCES.join(", ")}`;
|
|
70
|
+
}
|
|
71
|
+
const content = args.content === undefined ? undefined : asString(args.content);
|
|
72
|
+
const contentBase64 = args.contentBase64 === undefined
|
|
73
|
+
? undefined
|
|
74
|
+
: asString(args.contentBase64);
|
|
75
|
+
if ((content === undefined && contentBase64 === undefined) ||
|
|
76
|
+
(content !== undefined && contentBase64 !== undefined)) {
|
|
77
|
+
return "Error: provide exactly one of `content` or `contentBase64`";
|
|
78
|
+
}
|
|
79
|
+
const tags = Array.isArray(args.tags)
|
|
80
|
+
? args.tags.filter((t) => typeof t === "string")
|
|
81
|
+
: undefined;
|
|
82
|
+
try {
|
|
83
|
+
const entry = contentBase64 !== undefined
|
|
84
|
+
? await lib().addFile({
|
|
85
|
+
name,
|
|
86
|
+
mimeType,
|
|
87
|
+
source: sourceRaw,
|
|
88
|
+
buffer: Buffer.from(contentBase64, "base64"),
|
|
89
|
+
tags,
|
|
90
|
+
})
|
|
91
|
+
: await lib().addFile({
|
|
92
|
+
name,
|
|
93
|
+
mimeType,
|
|
94
|
+
source: sourceRaw,
|
|
95
|
+
content,
|
|
96
|
+
tags,
|
|
97
|
+
});
|
|
98
|
+
return JSON.stringify(fmtEntry(entry), null, 2);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
return `Error: ${err.message}`;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
export const fileLibraryListTool = {
|
|
106
|
+
name: "file_library_list",
|
|
107
|
+
description: "List files in the File Library, newest first. Optional filters: limit, since (ISO date), tag.",
|
|
108
|
+
tier: "free",
|
|
109
|
+
parameters: {
|
|
110
|
+
limit: { type: "number", description: "Max entries to return" },
|
|
111
|
+
since: {
|
|
112
|
+
type: "string",
|
|
113
|
+
description: "ISO 8601 date — only entries created at or after this time",
|
|
114
|
+
},
|
|
115
|
+
tag: { type: "string", description: "Filter to entries that have this tag" },
|
|
116
|
+
},
|
|
117
|
+
async execute(args) {
|
|
118
|
+
const limit = typeof args.limit === "number" ? args.limit : undefined;
|
|
119
|
+
const since = args.since === undefined ? undefined : asString(args.since);
|
|
120
|
+
const tag = args.tag === undefined ? undefined : asString(args.tag);
|
|
121
|
+
try {
|
|
122
|
+
const entries = await lib().listFiles({ limit, since, tag });
|
|
123
|
+
return JSON.stringify({ count: entries.length, entries: entries.map(fmtEntry) }, null, 2);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
return `Error: ${err.message}`;
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
export const fileLibrarySearchTool = {
|
|
131
|
+
name: "file_library_search",
|
|
132
|
+
description: "Search the File Library. Modes: 'name' (substring on name), 'content' (substring on text contents), 'both' (union).",
|
|
133
|
+
tier: "free",
|
|
134
|
+
parameters: {
|
|
135
|
+
query: { type: "string", description: "Substring to match", required: true },
|
|
136
|
+
mode: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description: "'name' | 'content' | 'both'",
|
|
139
|
+
required: true,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
async execute(args) {
|
|
143
|
+
const query = asString(args.query);
|
|
144
|
+
const mode = asString(args.mode);
|
|
145
|
+
if (mode !== "name" && mode !== "content" && mode !== "both") {
|
|
146
|
+
return "Error: mode must be 'name' | 'content' | 'both'";
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const entries = await lib().searchFiles({ query, mode });
|
|
150
|
+
return JSON.stringify({ count: entries.length, entries: entries.map(fmtEntry) }, null, 2);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
return `Error: ${err.message}`;
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
export const fileLibraryGetTool = {
|
|
158
|
+
name: "file_library_get",
|
|
159
|
+
description: "Fetch a file by id. For text mimes returns utf-8 content; for binary returns base64.",
|
|
160
|
+
tier: "free",
|
|
161
|
+
parameters: {
|
|
162
|
+
id: { type: "string", description: "File id (sha256 hex)", required: true },
|
|
163
|
+
encoding: {
|
|
164
|
+
type: "string",
|
|
165
|
+
description: "'utf8' | 'base64' (default: auto by mimeType)",
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
async execute(args) {
|
|
169
|
+
const id = asString(args.id);
|
|
170
|
+
const encodingArg = args.encoding === undefined ? undefined : asString(args.encoding);
|
|
171
|
+
try {
|
|
172
|
+
const got = await lib().getFile(id);
|
|
173
|
+
if (!got)
|
|
174
|
+
return `Error: file not found: ${id}`;
|
|
175
|
+
const { entry, buffer } = got;
|
|
176
|
+
const isText = /^text\//i.test(entry.mimeType) ||
|
|
177
|
+
/^application\/(json|yaml|x-yaml|xml|javascript|typescript)$/i.test(entry.mimeType);
|
|
178
|
+
const encoding = encodingArg === "utf8" || encodingArg === "base64"
|
|
179
|
+
? encodingArg
|
|
180
|
+
: isText
|
|
181
|
+
? "utf8"
|
|
182
|
+
: "base64";
|
|
183
|
+
const content = encoding === "utf8" ? buffer.toString("utf8") : buffer.toString("base64");
|
|
184
|
+
return JSON.stringify({ entry: fmtEntry(entry), encoding, content }, null, 2);
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
return `Error: ${err.message}`;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=file-library-tools.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ToolDefinition } from './index.js';
|
|
3
|
+
export declare const imageThoughtfulInputSchema: z.ZodObject<{
|
|
4
|
+
prompt: z.ZodString;
|
|
5
|
+
aspect_ratio: z.ZodDefault<z.ZodOptional<z.ZodEnum<["1:1", "16:9", "9:16", "4:3", "3:4"]>>>;
|
|
6
|
+
thinking_steps: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
7
|
+
style_hints: z.ZodOptional<z.ZodString>;
|
|
8
|
+
reference_image_url: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
prompt: string;
|
|
11
|
+
aspect_ratio: "1:1" | "16:9" | "9:16" | "4:3" | "3:4";
|
|
12
|
+
thinking_steps: number;
|
|
13
|
+
style_hints?: string | undefined;
|
|
14
|
+
reference_image_url?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
prompt: string;
|
|
17
|
+
aspect_ratio?: "1:1" | "16:9" | "9:16" | "4:3" | "3:4" | undefined;
|
|
18
|
+
thinking_steps?: number | undefined;
|
|
19
|
+
style_hints?: string | undefined;
|
|
20
|
+
reference_image_url?: string | undefined;
|
|
21
|
+
}>;
|
|
22
|
+
export type ImageThoughtfulInput = z.infer<typeof imageThoughtfulInputSchema>;
|
|
23
|
+
export interface ImageThoughtfulOutput {
|
|
24
|
+
url: string;
|
|
25
|
+
plan: string;
|
|
26
|
+
refinements: string[];
|
|
27
|
+
final_prompt: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function runImageThoughtful(rawInput: unknown, env?: NodeJS.ProcessEnv): Promise<ImageThoughtfulOutput>;
|
|
30
|
+
export declare const imageThoughtfulTool: ToolDefinition;
|
|
31
|
+
//# sourceMappingURL=image-thoughtful.d.ts.map
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// kbot Image Thoughtful Tool
|
|
2
|
+
// Mirrors OpenAI's "Images 2.0 with thinking": plan → refine (1..N) → generate.
|
|
3
|
+
// The thinking phase uses gpt-4o-mini chat completions; the final generation
|
|
4
|
+
// hits the OpenAI Images API (gpt-image-2). Reference images are forwarded as
|
|
5
|
+
// input_image when supplied.
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
8
|
+
// Schema
|
|
9
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
10
|
+
const AspectRatio = z.enum(['1:1', '16:9', '9:16', '4:3', '3:4']);
|
|
11
|
+
export const imageThoughtfulInputSchema = z.object({
|
|
12
|
+
prompt: z.string().min(1, 'prompt is required'),
|
|
13
|
+
aspect_ratio: AspectRatio.optional().default('1:1'),
|
|
14
|
+
thinking_steps: z.number().int().min(1).max(5).optional().default(3),
|
|
15
|
+
style_hints: z.string().optional(),
|
|
16
|
+
reference_image_url: z.string().url().optional(),
|
|
17
|
+
});
|
|
18
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
19
|
+
// Aspect ratio → image API "size"
|
|
20
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
21
|
+
const SIZE_MAP = {
|
|
22
|
+
'1:1': '1024x1024',
|
|
23
|
+
'16:9': '1792x1024',
|
|
24
|
+
'9:16': '1024x1792',
|
|
25
|
+
'4:3': '1408x1056',
|
|
26
|
+
'3:4': '1056x1408',
|
|
27
|
+
};
|
|
28
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
29
|
+
// OpenAI helpers (built-in fetch, no SDK)
|
|
30
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
31
|
+
const OPENAI_CHAT_URL = 'https://api.openai.com/v1/chat/completions';
|
|
32
|
+
const OPENAI_IMAGE_URL = 'https://api.openai.com/v1/images/generations';
|
|
33
|
+
const PLANNING_MODEL = 'gpt-4o-mini';
|
|
34
|
+
const IMAGE_MODEL = 'gpt-image-2';
|
|
35
|
+
async function openaiChat(apiKey, messages, opts = {}) {
|
|
36
|
+
const body = {
|
|
37
|
+
model: PLANNING_MODEL,
|
|
38
|
+
messages,
|
|
39
|
+
temperature: opts.temperature ?? 0.4,
|
|
40
|
+
};
|
|
41
|
+
if (opts.jsonMode) {
|
|
42
|
+
body.response_format = { type: 'json_object' };
|
|
43
|
+
}
|
|
44
|
+
const res = await fetch(OPENAI_CHAT_URL, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Bearer ${apiKey}`,
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify(body),
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
const text = await res.text().catch(() => '');
|
|
54
|
+
throw new Error(`OpenAI chat failed: ${res.status} ${res.statusText} ${text}`.trim());
|
|
55
|
+
}
|
|
56
|
+
const data = (await res.json());
|
|
57
|
+
const content = data.choices?.[0]?.message?.content;
|
|
58
|
+
if (!content) {
|
|
59
|
+
throw new Error('OpenAI chat returned no content');
|
|
60
|
+
}
|
|
61
|
+
return content;
|
|
62
|
+
}
|
|
63
|
+
async function openaiImage(apiKey, prompt, size, referenceImageUrl) {
|
|
64
|
+
const body = {
|
|
65
|
+
model: IMAGE_MODEL,
|
|
66
|
+
prompt,
|
|
67
|
+
size,
|
|
68
|
+
n: 1,
|
|
69
|
+
};
|
|
70
|
+
if (referenceImageUrl) {
|
|
71
|
+
body.input_image = referenceImageUrl;
|
|
72
|
+
}
|
|
73
|
+
const res = await fetch(OPENAI_IMAGE_URL, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: `Bearer ${apiKey}`,
|
|
77
|
+
'Content-Type': 'application/json',
|
|
78
|
+
},
|
|
79
|
+
body: JSON.stringify(body),
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const text = await res.text().catch(() => '');
|
|
83
|
+
throw new Error(`OpenAI image failed: ${res.status} ${res.statusText} ${text}`.trim());
|
|
84
|
+
}
|
|
85
|
+
const data = (await res.json());
|
|
86
|
+
const url = data.data?.[0]?.url;
|
|
87
|
+
if (!url) {
|
|
88
|
+
// gpt-image-* sometimes returns b64; surface that as a data URL
|
|
89
|
+
const b64 = data.data?.[0]?.b64_json;
|
|
90
|
+
if (b64)
|
|
91
|
+
return `data:image/png;base64,${b64}`;
|
|
92
|
+
throw new Error('OpenAI image returned no url');
|
|
93
|
+
}
|
|
94
|
+
return url;
|
|
95
|
+
}
|
|
96
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
97
|
+
// Plan + refine loop
|
|
98
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
99
|
+
function planSystemPrompt() {
|
|
100
|
+
return [
|
|
101
|
+
'You are an expert art director planning an image before generation.',
|
|
102
|
+
'Return a JSON object with keys: composition, palette, key_elements, mood, lighting, style.',
|
|
103
|
+
'Keep each value to one or two sentences. Be concrete and visual.',
|
|
104
|
+
].join(' ');
|
|
105
|
+
}
|
|
106
|
+
function critiqueSystemPrompt() {
|
|
107
|
+
return [
|
|
108
|
+
'You are a critic refining an image plan. Read the prompt and the current plan,',
|
|
109
|
+
'identify the single weakest element, and return an improved JSON plan with the',
|
|
110
|
+
'same keys (composition, palette, key_elements, mood, lighting, style).',
|
|
111
|
+
'Do not restate the brief — produce the next iteration of the plan only.',
|
|
112
|
+
].join(' ');
|
|
113
|
+
}
|
|
114
|
+
function finalPromptSystemPrompt() {
|
|
115
|
+
return [
|
|
116
|
+
'You compose the final image-generation prompt. Combine the brief, plan, and any',
|
|
117
|
+
'style hints into a single cohesive paragraph (no JSON, no headings, no lists).',
|
|
118
|
+
'Lead with subject and composition, then palette, lighting, mood, and style.',
|
|
119
|
+
].join(' ');
|
|
120
|
+
}
|
|
121
|
+
function buildPlanUserContent(input) {
|
|
122
|
+
const parts = [
|
|
123
|
+
{
|
|
124
|
+
type: 'text',
|
|
125
|
+
text: [
|
|
126
|
+
`Brief: ${input.prompt}`,
|
|
127
|
+
`Aspect ratio: ${input.aspect_ratio}`,
|
|
128
|
+
input.style_hints ? `Style hints: ${input.style_hints}` : null,
|
|
129
|
+
]
|
|
130
|
+
.filter(Boolean)
|
|
131
|
+
.join('\n'),
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
if (input.reference_image_url) {
|
|
135
|
+
parts.push({ type: 'input_image', image_url: input.reference_image_url });
|
|
136
|
+
}
|
|
137
|
+
return parts;
|
|
138
|
+
}
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
140
|
+
// Tool definition
|
|
141
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
142
|
+
export async function runImageThoughtful(rawInput, env = process.env) {
|
|
143
|
+
const input = imageThoughtfulInputSchema.parse(rawInput);
|
|
144
|
+
const apiKey = env.OPENAI_API_KEY;
|
|
145
|
+
if (!apiKey) {
|
|
146
|
+
throw new Error('OPENAI_API_KEY is not set');
|
|
147
|
+
}
|
|
148
|
+
// 1. Plan
|
|
149
|
+
const plan = await openaiChat(apiKey, [
|
|
150
|
+
{ role: 'system', content: planSystemPrompt() },
|
|
151
|
+
{ role: 'user', content: buildPlanUserContent(input) },
|
|
152
|
+
], { jsonMode: true, temperature: 0.5 });
|
|
153
|
+
// 2. Refine (thinking_steps - 1 critiques; thinking_steps=1 means no refinement)
|
|
154
|
+
const refinements = [];
|
|
155
|
+
let currentPlan = plan;
|
|
156
|
+
for (let i = 1; i < input.thinking_steps; i++) {
|
|
157
|
+
const next = await openaiChat(apiKey, [
|
|
158
|
+
{ role: 'system', content: critiqueSystemPrompt() },
|
|
159
|
+
{
|
|
160
|
+
role: 'user',
|
|
161
|
+
content: [
|
|
162
|
+
{ type: 'text', text: `Brief: ${input.prompt}` },
|
|
163
|
+
{ type: 'text', text: `Current plan: ${currentPlan}` },
|
|
164
|
+
],
|
|
165
|
+
},
|
|
166
|
+
], { jsonMode: true, temperature: 0.5 });
|
|
167
|
+
refinements.push(next);
|
|
168
|
+
currentPlan = next;
|
|
169
|
+
}
|
|
170
|
+
// 3. Compose final prompt
|
|
171
|
+
const finalPromptText = await openaiChat(apiKey, [
|
|
172
|
+
{ role: 'system', content: finalPromptSystemPrompt() },
|
|
173
|
+
{
|
|
174
|
+
role: 'user',
|
|
175
|
+
content: [
|
|
176
|
+
`Brief: ${input.prompt}`,
|
|
177
|
+
input.style_hints ? `Style hints: ${input.style_hints}` : '',
|
|
178
|
+
`Plan: ${currentPlan}`,
|
|
179
|
+
]
|
|
180
|
+
.filter(Boolean)
|
|
181
|
+
.join('\n\n'),
|
|
182
|
+
},
|
|
183
|
+
], { temperature: 0.4 });
|
|
184
|
+
// 4. Generate
|
|
185
|
+
const url = await openaiImage(apiKey, finalPromptText, SIZE_MAP[input.aspect_ratio], input.reference_image_url);
|
|
186
|
+
return {
|
|
187
|
+
url,
|
|
188
|
+
plan,
|
|
189
|
+
refinements,
|
|
190
|
+
final_prompt: finalPromptText,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export const imageThoughtfulTool = {
|
|
194
|
+
name: 'image_thoughtful',
|
|
195
|
+
description: 'Generate an image with an explicit plan/refine loop. Plans the image (composition, palette, key elements), critiques and refines the plan, then issues the final OpenAI image generation. Returns the image URL plus the full reasoning trail.',
|
|
196
|
+
tier: 'pro',
|
|
197
|
+
parameters: {
|
|
198
|
+
prompt: {
|
|
199
|
+
type: 'string',
|
|
200
|
+
description: 'What to draw — the brief.',
|
|
201
|
+
required: true,
|
|
202
|
+
},
|
|
203
|
+
aspect_ratio: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'One of "1:1", "16:9", "9:16", "4:3", "3:4". Default "1:1".',
|
|
206
|
+
default: '1:1',
|
|
207
|
+
},
|
|
208
|
+
thinking_steps: {
|
|
209
|
+
type: 'number',
|
|
210
|
+
description: 'How many plan iterations to run (1..5). Default 3. 1 skips refinement.',
|
|
211
|
+
default: 3,
|
|
212
|
+
},
|
|
213
|
+
style_hints: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
description: 'Optional style guidance ("oil painting", "ukiyo-e", "isometric vector").',
|
|
216
|
+
},
|
|
217
|
+
reference_image_url: {
|
|
218
|
+
type: 'string',
|
|
219
|
+
description: 'Optional URL of a reference image. Passed to the planning model and forwarded to the image API as input_image.',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
async execute(args) {
|
|
223
|
+
try {
|
|
224
|
+
const out = await runImageThoughtful(args);
|
|
225
|
+
return JSON.stringify(out, null, 2);
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
229
|
+
return `Error: ${message}`;
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=image-thoughtful.js.map
|
package/dist/tools/index.js
CHANGED
|
@@ -338,6 +338,7 @@ const LAZY_MODULE_IMPORTS = [
|
|
|
338
338
|
{ path: './stream-vod.js', registerFn: 'registerStreamVODTools' },
|
|
339
339
|
{ path: './stream-commands.js', registerFn: 'registerStreamCommandsTools' },
|
|
340
340
|
{ path: '../coordinator.js', registerFn: 'registerCoordinatorTools' },
|
|
341
|
+
{ path: './swarm-2026-04.js', registerFn: 'registerSwarm2026Tools' },
|
|
341
342
|
];
|
|
342
343
|
/** Track whether lazy tools have been registered */
|
|
343
344
|
let lazyToolsRegistered = false;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type SecurityReport } from '../agents/security-agent.js';
|
|
3
|
+
export declare const securityAgentScanSchema: z.ZodObject<{
|
|
4
|
+
target: z.ZodString;
|
|
5
|
+
mode: z.ZodDefault<z.ZodEnum<["scan", "scan-and-fix", "report-only"]>>;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
target: string;
|
|
8
|
+
mode: "scan" | "scan-and-fix" | "report-only";
|
|
9
|
+
}, {
|
|
10
|
+
target: string;
|
|
11
|
+
mode?: "scan" | "scan-and-fix" | "report-only" | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const securityAgentReportSchema: z.ZodObject<{
|
|
14
|
+
target: z.ZodString;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
target: string;
|
|
17
|
+
}, {
|
|
18
|
+
target: string;
|
|
19
|
+
}>;
|
|
20
|
+
export interface SecurityAgentToolDef<TArgs, TResult> {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
schema: z.ZodTypeAny;
|
|
24
|
+
run: (args: TArgs) => Promise<TResult>;
|
|
25
|
+
}
|
|
26
|
+
export declare const securityAgentScan: SecurityAgentToolDef<z.infer<typeof securityAgentScanSchema>, SecurityReport>;
|
|
27
|
+
export declare const securityAgentReport: SecurityAgentToolDef<z.infer<typeof securityAgentReportSchema>, string>;
|
|
28
|
+
export declare const SECURITY_AGENT_TOOLS: (SecurityAgentToolDef<{
|
|
29
|
+
target: string;
|
|
30
|
+
mode: "scan" | "scan-and-fix" | "report-only";
|
|
31
|
+
}, SecurityReport> | SecurityAgentToolDef<{
|
|
32
|
+
target: string;
|
|
33
|
+
}, string>)[];
|
|
34
|
+
//# sourceMappingURL=security-agent-tools.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// kbot tool definitions for the unified security agent.
|
|
2
|
+
// NOT registered in tools/index.ts — wire them in deliberately when promoting
|
|
3
|
+
// the security agent surface (see guardian/hacker integration notes).
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { runSecurityAgent } from '../agents/security-agent.js';
|
|
6
|
+
export const securityAgentScanSchema = z.object({
|
|
7
|
+
target: z.string().describe('Absolute or relative directory to scan'),
|
|
8
|
+
mode: z.enum(['scan', 'scan-and-fix', 'report-only']).default('scan'),
|
|
9
|
+
});
|
|
10
|
+
export const securityAgentReportSchema = z.object({
|
|
11
|
+
target: z.string().describe('Directory to scan and produce a Markdown report for'),
|
|
12
|
+
});
|
|
13
|
+
export const securityAgentScan = {
|
|
14
|
+
name: 'security_agent_scan',
|
|
15
|
+
description: 'Run the kbot security agent over a directory. Modes: scan | scan-and-fix | report-only. ' +
|
|
16
|
+
'Returns the full structured SecurityReport.',
|
|
17
|
+
schema: securityAgentScanSchema,
|
|
18
|
+
run: async (args) => runSecurityAgent({ target: args.target, mode: args.mode }),
|
|
19
|
+
};
|
|
20
|
+
export const securityAgentReport = {
|
|
21
|
+
name: 'security_agent_report',
|
|
22
|
+
description: 'Run the kbot security agent in read-only mode and return only the Markdown summary.',
|
|
23
|
+
schema: securityAgentReportSchema,
|
|
24
|
+
run: async (args) => {
|
|
25
|
+
const report = await runSecurityAgent({ target: args.target, mode: 'report-only' });
|
|
26
|
+
return report.summary;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export const SECURITY_AGENT_TOOLS = [securityAgentScan, securityAgentReport];
|
|
30
|
+
//# sourceMappingURL=security-agent-tools.js.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Tools landed via the 2026-04 capability swarm — parity with OpenClaw +
|
|
2
|
+
// ChatGPT/Codex April 2026 ships. Single registration entry-point so the
|
|
3
|
+
// lazy registry picks them up alongside everything else.
|
|
4
|
+
import { registerTool } from './index.js';
|
|
5
|
+
import { imageThoughtfulTool } from './image-thoughtful.js';
|
|
6
|
+
import { channelSendTool, channelReceiveTool } from './channel-tools.js';
|
|
7
|
+
import { fileLibraryAddTool, fileLibraryListTool, fileLibrarySearchTool, fileLibraryGetTool, } from './file-library-tools.js';
|
|
8
|
+
import { workspaceAgentTools } from './workspace-agent-tools.js';
|
|
9
|
+
import { computerCoordinatorTools } from './computer-coordinator-tools.js';
|
|
10
|
+
import { SECURITY_AGENT_TOOLS } from './security-agent-tools.js';
|
|
11
|
+
import { anthropicManagedAgentTools } from './anthropic-managed-agents-tools.js';
|
|
12
|
+
function adaptCoordinatorTool(t) {
|
|
13
|
+
const props = t.inputSchema.properties ?? {};
|
|
14
|
+
const required = new Set(t.inputSchema.required ?? []);
|
|
15
|
+
const parameters = {};
|
|
16
|
+
for (const [key, val] of Object.entries(props)) {
|
|
17
|
+
parameters[key] = {
|
|
18
|
+
type: val.type ?? 'string',
|
|
19
|
+
description: val.description ?? '',
|
|
20
|
+
required: required.has(key),
|
|
21
|
+
...(val.items ? { items: val.items } : {}),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
name: t.name,
|
|
26
|
+
description: t.description,
|
|
27
|
+
parameters,
|
|
28
|
+
execute: async (args) => {
|
|
29
|
+
try {
|
|
30
|
+
const res = await t.handler(args);
|
|
31
|
+
return typeof res === 'string' ? res : JSON.stringify(res, null, 2);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
return `Error: ${e.message}`;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
tier: 'free',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function adaptSecurityTool(t) {
|
|
41
|
+
// zod object shape extraction — best-effort parameter map for the API surface
|
|
42
|
+
const shape = t.schema._def?.shape?.() ??
|
|
43
|
+
t.schema.shape ??
|
|
44
|
+
{};
|
|
45
|
+
const parameters = {};
|
|
46
|
+
for (const [key, zodType] of Object.entries(shape)) {
|
|
47
|
+
const optional = typeof zodType.isOptional === 'function'
|
|
48
|
+
? zodType.isOptional()
|
|
49
|
+
: false;
|
|
50
|
+
parameters[key] = {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: zodType.description ?? '',
|
|
53
|
+
required: !optional,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
name: t.name,
|
|
58
|
+
description: t.description,
|
|
59
|
+
parameters,
|
|
60
|
+
execute: async (args) => {
|
|
61
|
+
try {
|
|
62
|
+
const parsed = t.schema.parse(args);
|
|
63
|
+
const res = await t.run(parsed);
|
|
64
|
+
return typeof res === 'string' ? res : JSON.stringify(res, null, 2);
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
return `Error: ${e.message}`;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
tier: 'free',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function registerSwarm2026Tools() {
|
|
74
|
+
registerTool(imageThoughtfulTool);
|
|
75
|
+
registerTool(channelSendTool);
|
|
76
|
+
registerTool(channelReceiveTool);
|
|
77
|
+
registerTool(fileLibraryAddTool);
|
|
78
|
+
registerTool(fileLibraryListTool);
|
|
79
|
+
registerTool(fileLibrarySearchTool);
|
|
80
|
+
registerTool(fileLibraryGetTool);
|
|
81
|
+
for (const t of workspaceAgentTools)
|
|
82
|
+
registerTool(t);
|
|
83
|
+
for (const t of anthropicManagedAgentTools)
|
|
84
|
+
registerTool(t);
|
|
85
|
+
for (const t of computerCoordinatorTools)
|
|
86
|
+
registerTool(adaptCoordinatorTool(t));
|
|
87
|
+
for (const t of SECURITY_AGENT_TOOLS) {
|
|
88
|
+
registerTool(adaptSecurityTool(t));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=swarm-2026-04.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Agent kbot tool definitions.
|
|
3
|
+
*
|
|
4
|
+
* NOT registered in tools/index.ts. Wire up via `registerWorkspaceAgentTools()`
|
|
5
|
+
* from a higher-level bootstrap once the feature is shipped.
|
|
6
|
+
*
|
|
7
|
+
* Each tool returns a string (the kbot tool contract). State persists via
|
|
8
|
+
* the WorkspaceAgent class — file at <root>/<id>.json.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolDefinition } from './index.js';
|
|
11
|
+
export declare const workspaceAgentCreate: ToolDefinition;
|
|
12
|
+
export declare const workspaceAgentStart: ToolDefinition;
|
|
13
|
+
export declare const workspaceAgentResume: ToolDefinition;
|
|
14
|
+
export declare const workspaceAgentStatus: ToolDefinition;
|
|
15
|
+
export declare const workspaceAgentStop: ToolDefinition;
|
|
16
|
+
export declare const workspaceAgentList: ToolDefinition;
|
|
17
|
+
/** Convenience array — caller can iterate to register all six. */
|
|
18
|
+
export declare const workspaceAgentTools: ToolDefinition[];
|
|
19
|
+
//# sourceMappingURL=workspace-agent-tools.d.ts.map
|