llmist 16.1.0 → 16.2.1
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/dist/index.cjs +884 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +486 -2
- package/dist/index.d.ts +486 -2
- package/dist/index.js +864 -51
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -358,15 +358,15 @@ var init_execution_tree = __esm({
|
|
|
358
358
|
const parentId = params.parentId ?? this.parentNodeId;
|
|
359
359
|
const parent = parentId ? this.nodes.get(parentId) : null;
|
|
360
360
|
const depth = parent ? parent.depth + 1 : this.baseDepth;
|
|
361
|
-
const
|
|
361
|
+
const path3 = parent ? [...parent.path] : [];
|
|
362
362
|
const id = this.generateLLMCallId(params.iteration, parentId);
|
|
363
|
-
|
|
363
|
+
path3.push(id);
|
|
364
364
|
const node = {
|
|
365
365
|
id,
|
|
366
366
|
type: "llm_call",
|
|
367
367
|
parentId,
|
|
368
368
|
depth,
|
|
369
|
-
path,
|
|
369
|
+
path: path3,
|
|
370
370
|
createdAt: Date.now(),
|
|
371
371
|
completedAt: null,
|
|
372
372
|
iteration: params.iteration,
|
|
@@ -477,15 +477,15 @@ var init_execution_tree = __esm({
|
|
|
477
477
|
const parentId = params.parentId ?? this.getCurrentLLMCallId() ?? this.parentNodeId;
|
|
478
478
|
const parent = parentId ? this.nodes.get(parentId) : null;
|
|
479
479
|
const depth = parent ? parent.depth + 1 : this.baseDepth;
|
|
480
|
-
const
|
|
480
|
+
const path3 = parent ? [...parent.path] : [];
|
|
481
481
|
const id = this.generateGadgetId(params.invocationId);
|
|
482
|
-
|
|
482
|
+
path3.push(id);
|
|
483
483
|
const node = {
|
|
484
484
|
id,
|
|
485
485
|
type: "gadget",
|
|
486
486
|
parentId,
|
|
487
487
|
depth,
|
|
488
|
-
path,
|
|
488
|
+
path: path3,
|
|
489
489
|
createdAt: Date.now(),
|
|
490
490
|
completedAt: null,
|
|
491
491
|
invocationId: params.invocationId,
|
|
@@ -1424,8 +1424,8 @@ ${this.endPrefix}`
|
|
|
1424
1424
|
});
|
|
1425
1425
|
if (media && media.length > 0 && mediaIds && mediaIds.length > 0) {
|
|
1426
1426
|
const idRefs = media.map((m, i) => {
|
|
1427
|
-
const
|
|
1428
|
-
const pathInfo =
|
|
1427
|
+
const path3 = storedMedia?.[i]?.path;
|
|
1428
|
+
const pathInfo = path3 ? ` \u2192 saved to: ${path3}` : "";
|
|
1429
1429
|
return `[Media: ${mediaIds[i]} (${m.kind})${pathInfo}]`;
|
|
1430
1430
|
}).join("\n");
|
|
1431
1431
|
const textWithIds = `Result (${invocationId}): ${result}
|
|
@@ -4032,29 +4032,29 @@ function schemaToJSONSchema(schema, options) {
|
|
|
4032
4032
|
}
|
|
4033
4033
|
function detectDescriptionMismatch(schema, jsonSchema) {
|
|
4034
4034
|
const mismatches = [];
|
|
4035
|
-
function checkSchema(zodSchema, json,
|
|
4035
|
+
function checkSchema(zodSchema, json, path3) {
|
|
4036
4036
|
if (!zodSchema || typeof zodSchema !== "object") return;
|
|
4037
4037
|
const def = zodSchema._def;
|
|
4038
4038
|
const jsonObj = json;
|
|
4039
4039
|
if (def?.description && !jsonObj?.description) {
|
|
4040
|
-
mismatches.push(
|
|
4040
|
+
mismatches.push(path3 || "root");
|
|
4041
4041
|
}
|
|
4042
4042
|
if (def?.typeName === "ZodObject" && def?.shape) {
|
|
4043
4043
|
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
4044
4044
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
4045
4045
|
const properties = jsonObj?.properties;
|
|
4046
4046
|
const jsonProp = properties?.[key];
|
|
4047
|
-
checkSchema(fieldSchema, jsonProp,
|
|
4047
|
+
checkSchema(fieldSchema, jsonProp, path3 ? `${path3}.${key}` : key);
|
|
4048
4048
|
}
|
|
4049
4049
|
}
|
|
4050
4050
|
if (def?.typeName === "ZodArray" && def?.type) {
|
|
4051
|
-
checkSchema(def.type, jsonObj?.items,
|
|
4051
|
+
checkSchema(def.type, jsonObj?.items, path3 ? `${path3}[]` : "[]");
|
|
4052
4052
|
}
|
|
4053
4053
|
if ((def?.typeName === "ZodOptional" || def?.typeName === "ZodNullable") && def?.innerType) {
|
|
4054
|
-
checkSchema(def.innerType, json,
|
|
4054
|
+
checkSchema(def.innerType, json, path3);
|
|
4055
4055
|
}
|
|
4056
4056
|
if (def?.typeName === "ZodDefault" && def?.innerType) {
|
|
4057
|
-
checkSchema(def.innerType, json,
|
|
4057
|
+
checkSchema(def.innerType, json, path3);
|
|
4058
4058
|
}
|
|
4059
4059
|
}
|
|
4060
4060
|
checkSchema(schema, jsonSchema, "");
|
|
@@ -4147,7 +4147,7 @@ Example fixes:
|
|
|
4147
4147
|
);
|
|
4148
4148
|
}
|
|
4149
4149
|
}
|
|
4150
|
-
function findUnknownTypes(schema,
|
|
4150
|
+
function findUnknownTypes(schema, path3 = []) {
|
|
4151
4151
|
const issues = [];
|
|
4152
4152
|
if (!schema || typeof schema !== "object") {
|
|
4153
4153
|
return issues;
|
|
@@ -4159,7 +4159,7 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4159
4159
|
}
|
|
4160
4160
|
if (schema.properties) {
|
|
4161
4161
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
4162
|
-
const propPath = [...
|
|
4162
|
+
const propPath = [...path3, propName];
|
|
4163
4163
|
if (hasNoType(propSchema)) {
|
|
4164
4164
|
issues.push(propPath.join(".") || propName);
|
|
4165
4165
|
}
|
|
@@ -4167,7 +4167,7 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4167
4167
|
}
|
|
4168
4168
|
}
|
|
4169
4169
|
if (schema.items) {
|
|
4170
|
-
const itemPath = [...
|
|
4170
|
+
const itemPath = [...path3, "[]"];
|
|
4171
4171
|
if (hasNoType(schema.items)) {
|
|
4172
4172
|
issues.push(itemPath.join("."));
|
|
4173
4173
|
}
|
|
@@ -4175,17 +4175,17 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4175
4175
|
}
|
|
4176
4176
|
if (schema.anyOf) {
|
|
4177
4177
|
schema.anyOf.forEach((subSchema, index) => {
|
|
4178
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4178
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `anyOf[${index}]`]));
|
|
4179
4179
|
});
|
|
4180
4180
|
}
|
|
4181
4181
|
if (schema.oneOf) {
|
|
4182
4182
|
schema.oneOf.forEach((subSchema, index) => {
|
|
4183
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4183
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `oneOf[${index}]`]));
|
|
4184
4184
|
});
|
|
4185
4185
|
}
|
|
4186
4186
|
if (schema.allOf) {
|
|
4187
4187
|
schema.allOf.forEach((subSchema, index) => {
|
|
4188
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4188
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `allOf[${index}]`]));
|
|
4189
4189
|
});
|
|
4190
4190
|
}
|
|
4191
4191
|
return issues;
|
|
@@ -5203,6 +5203,626 @@ var init_registry = __esm({
|
|
|
5203
5203
|
}
|
|
5204
5204
|
});
|
|
5205
5205
|
|
|
5206
|
+
// src/skills/activation.ts
|
|
5207
|
+
function substituteArguments(instructions, args) {
|
|
5208
|
+
if (!args) {
|
|
5209
|
+
return instructions.replace(/\$ARGUMENTS\[\d+\]/g, "").replace(/\$ARGUMENTS/g, "").replace(/\$\d+/g, "");
|
|
5210
|
+
}
|
|
5211
|
+
const parts = splitArguments(args);
|
|
5212
|
+
let result = instructions.replace(/\$ARGUMENTS\[(\d+)\]/g, (_match, index) => {
|
|
5213
|
+
const i = Number.parseInt(index, 10);
|
|
5214
|
+
return parts[i] ?? "";
|
|
5215
|
+
});
|
|
5216
|
+
result = result.replace(/\$ARGUMENTS/g, args);
|
|
5217
|
+
result = result.replace(/\$(\d+)/g, (_match, index) => {
|
|
5218
|
+
const i = Number.parseInt(index, 10);
|
|
5219
|
+
return parts[i] ?? "";
|
|
5220
|
+
});
|
|
5221
|
+
return result;
|
|
5222
|
+
}
|
|
5223
|
+
function preprocessShellCommands(instructions, options) {
|
|
5224
|
+
const { cwd, shell = "bash", timeoutMs = 1e4 } = options ?? {};
|
|
5225
|
+
return instructions.replace(/!`([^`]+)`/g, (_match, command) => {
|
|
5226
|
+
try {
|
|
5227
|
+
const output = (0, import_node_child_process.execSync)(command, {
|
|
5228
|
+
cwd,
|
|
5229
|
+
shell: shell === "powershell" ? "powershell" : "/bin/bash",
|
|
5230
|
+
timeout: timeoutMs,
|
|
5231
|
+
encoding: "utf-8",
|
|
5232
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
5233
|
+
});
|
|
5234
|
+
return output.trim();
|
|
5235
|
+
} catch (error) {
|
|
5236
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
5237
|
+
return `[Error executing \`${command}\`: ${msg}]`;
|
|
5238
|
+
}
|
|
5239
|
+
});
|
|
5240
|
+
}
|
|
5241
|
+
function substituteVariables(instructions, variables) {
|
|
5242
|
+
return instructions.replace(/\$\{(\w+)\}/g, (_match, varName) => {
|
|
5243
|
+
return variables[varName] ?? "";
|
|
5244
|
+
});
|
|
5245
|
+
}
|
|
5246
|
+
function resolveInstructions(instructions, options) {
|
|
5247
|
+
let resolved = instructions;
|
|
5248
|
+
if (options?.variables) {
|
|
5249
|
+
resolved = substituteVariables(resolved, options.variables);
|
|
5250
|
+
}
|
|
5251
|
+
resolved = substituteArguments(resolved, options?.arguments);
|
|
5252
|
+
if (options?.enableShellPreprocessing !== false) {
|
|
5253
|
+
resolved = preprocessShellCommands(resolved, {
|
|
5254
|
+
cwd: options?.cwd,
|
|
5255
|
+
shell: options?.shell,
|
|
5256
|
+
timeoutMs: options?.shellTimeoutMs
|
|
5257
|
+
});
|
|
5258
|
+
}
|
|
5259
|
+
return resolved;
|
|
5260
|
+
}
|
|
5261
|
+
function splitArguments(args) {
|
|
5262
|
+
const parts = [];
|
|
5263
|
+
let current = "";
|
|
5264
|
+
let inQuote = null;
|
|
5265
|
+
for (const char of args) {
|
|
5266
|
+
if (inQuote) {
|
|
5267
|
+
if (char === inQuote) {
|
|
5268
|
+
inQuote = null;
|
|
5269
|
+
} else {
|
|
5270
|
+
current += char;
|
|
5271
|
+
}
|
|
5272
|
+
} else if (char === '"' || char === "'") {
|
|
5273
|
+
inQuote = char;
|
|
5274
|
+
} else if (char === " " || char === " ") {
|
|
5275
|
+
if (current) {
|
|
5276
|
+
parts.push(current);
|
|
5277
|
+
current = "";
|
|
5278
|
+
}
|
|
5279
|
+
} else {
|
|
5280
|
+
current += char;
|
|
5281
|
+
}
|
|
5282
|
+
}
|
|
5283
|
+
if (current) parts.push(current);
|
|
5284
|
+
return parts;
|
|
5285
|
+
}
|
|
5286
|
+
var import_node_child_process;
|
|
5287
|
+
var init_activation = __esm({
|
|
5288
|
+
"src/skills/activation.ts"() {
|
|
5289
|
+
"use strict";
|
|
5290
|
+
import_node_child_process = require("child_process");
|
|
5291
|
+
}
|
|
5292
|
+
});
|
|
5293
|
+
|
|
5294
|
+
// src/skills/parser.ts
|
|
5295
|
+
function parseFrontmatter(content) {
|
|
5296
|
+
const trimmed = content.trimStart();
|
|
5297
|
+
if (!trimmed.startsWith("---")) {
|
|
5298
|
+
return { frontmatter: {}, body: content };
|
|
5299
|
+
}
|
|
5300
|
+
const endIndex = trimmed.indexOf("\n---", 3);
|
|
5301
|
+
if (endIndex === -1) {
|
|
5302
|
+
return { frontmatter: {}, body: content };
|
|
5303
|
+
}
|
|
5304
|
+
const yamlBlock = trimmed.slice(3, endIndex).trim();
|
|
5305
|
+
const body = trimmed.slice(endIndex + 4).trim();
|
|
5306
|
+
const parsed = import_js_yaml.default.load(yamlBlock);
|
|
5307
|
+
const frontmatter = typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
5308
|
+
return { frontmatter, body };
|
|
5309
|
+
}
|
|
5310
|
+
function parseMetadata(frontmatter, fallbackName) {
|
|
5311
|
+
const name = parseString(frontmatter.name) ?? fallbackName ?? "unnamed-skill";
|
|
5312
|
+
const description = parseString(frontmatter.description) ?? "";
|
|
5313
|
+
return {
|
|
5314
|
+
name,
|
|
5315
|
+
description,
|
|
5316
|
+
argumentHint: parseString(frontmatter["argument-hint"]),
|
|
5317
|
+
allowedTools: parseStringArray(frontmatter["allowed-tools"]),
|
|
5318
|
+
model: parseString(frontmatter.model),
|
|
5319
|
+
context: parseContext(frontmatter.context),
|
|
5320
|
+
agent: parseString(frontmatter.agent),
|
|
5321
|
+
paths: parseStringArray(frontmatter.paths),
|
|
5322
|
+
gadgets: parseStringArray(frontmatter.gadgets),
|
|
5323
|
+
disableModelInvocation: parseBool(frontmatter["disable-model-invocation"]),
|
|
5324
|
+
userInvocable: parseBool(frontmatter["user-invocable"]),
|
|
5325
|
+
shell: parseShell(frontmatter.shell),
|
|
5326
|
+
version: parseString(frontmatter.version)
|
|
5327
|
+
};
|
|
5328
|
+
}
|
|
5329
|
+
function scanResources(skillDir) {
|
|
5330
|
+
const resources = [];
|
|
5331
|
+
for (const category of RESOURCE_CATEGORIES) {
|
|
5332
|
+
const categoryDir = import_node_path3.default.join(skillDir, category);
|
|
5333
|
+
if (!import_node_fs2.default.existsSync(categoryDir)) continue;
|
|
5334
|
+
const stat = import_node_fs2.default.statSync(categoryDir);
|
|
5335
|
+
if (!stat.isDirectory()) continue;
|
|
5336
|
+
for (const file of walkDirectory(categoryDir)) {
|
|
5337
|
+
resources.push({
|
|
5338
|
+
relativePath: import_node_path3.default.relative(skillDir, file),
|
|
5339
|
+
absolutePath: file,
|
|
5340
|
+
category
|
|
5341
|
+
});
|
|
5342
|
+
}
|
|
5343
|
+
}
|
|
5344
|
+
return resources;
|
|
5345
|
+
}
|
|
5346
|
+
function parseSkillFile(skillMdPath, source, loadInstructions = false) {
|
|
5347
|
+
const content = import_node_fs2.default.readFileSync(skillMdPath, "utf-8");
|
|
5348
|
+
return parseSkillContent(content, skillMdPath, source, loadInstructions);
|
|
5349
|
+
}
|
|
5350
|
+
function parseSkillContent(content, sourcePath, source, loadInstructions = false) {
|
|
5351
|
+
const sourceDir = import_node_path3.default.dirname(sourcePath);
|
|
5352
|
+
const fallbackName = import_node_path3.default.basename(sourceDir);
|
|
5353
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
5354
|
+
const metadata = parseMetadata(frontmatter, fallbackName);
|
|
5355
|
+
const resources = import_node_fs2.default.existsSync(sourceDir) ? scanResources(sourceDir) : [];
|
|
5356
|
+
return {
|
|
5357
|
+
metadata,
|
|
5358
|
+
instructions: loadInstructions ? body : null,
|
|
5359
|
+
resources,
|
|
5360
|
+
sourcePath,
|
|
5361
|
+
sourceDir,
|
|
5362
|
+
source
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
function validateMetadata(metadata) {
|
|
5366
|
+
const issues = [];
|
|
5367
|
+
if (!metadata.name) {
|
|
5368
|
+
issues.push("Skill name is required");
|
|
5369
|
+
} else {
|
|
5370
|
+
if (metadata.name.length > MAX_NAME_LENGTH) {
|
|
5371
|
+
issues.push(`Skill name exceeds ${MAX_NAME_LENGTH} characters`);
|
|
5372
|
+
}
|
|
5373
|
+
if (!NAME_PATTERN.test(metadata.name)) {
|
|
5374
|
+
issues.push(
|
|
5375
|
+
"Skill name must contain only lowercase letters, numbers, and hyphens, and must start with a letter or number"
|
|
5376
|
+
);
|
|
5377
|
+
}
|
|
5378
|
+
}
|
|
5379
|
+
if (!metadata.description) {
|
|
5380
|
+
issues.push("Skill description is required");
|
|
5381
|
+
} else if (metadata.description.length > MAX_DESCRIPTION_LENGTH) {
|
|
5382
|
+
issues.push(`Skill description exceeds ${MAX_DESCRIPTION_LENGTH} characters`);
|
|
5383
|
+
}
|
|
5384
|
+
if (metadata.context && metadata.context !== "fork" && metadata.context !== "inline") {
|
|
5385
|
+
issues.push('Skill context must be "fork" or "inline"');
|
|
5386
|
+
}
|
|
5387
|
+
return issues;
|
|
5388
|
+
}
|
|
5389
|
+
function parseString(value) {
|
|
5390
|
+
if (value == null) return void 0;
|
|
5391
|
+
if (typeof value === "string") return value;
|
|
5392
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
5393
|
+
return void 0;
|
|
5394
|
+
}
|
|
5395
|
+
function parseStringArray(value) {
|
|
5396
|
+
if (value == null) return void 0;
|
|
5397
|
+
if (Array.isArray(value)) {
|
|
5398
|
+
return value.filter((v) => typeof v === "string" || typeof v === "number").map(String);
|
|
5399
|
+
}
|
|
5400
|
+
if (typeof value === "string") return [value];
|
|
5401
|
+
return void 0;
|
|
5402
|
+
}
|
|
5403
|
+
function parseContext(value) {
|
|
5404
|
+
if (value === "fork" || value === "inline") return value;
|
|
5405
|
+
return void 0;
|
|
5406
|
+
}
|
|
5407
|
+
function parseShell(value) {
|
|
5408
|
+
if (value === "bash" || value === "powershell") return value;
|
|
5409
|
+
return void 0;
|
|
5410
|
+
}
|
|
5411
|
+
function parseBool(value) {
|
|
5412
|
+
if (value === true || value === false) return value;
|
|
5413
|
+
if (value === "true") return true;
|
|
5414
|
+
if (value === "false") return false;
|
|
5415
|
+
return void 0;
|
|
5416
|
+
}
|
|
5417
|
+
function* walkDirectory(dir) {
|
|
5418
|
+
const entries = import_node_fs2.default.readdirSync(dir, { withFileTypes: true });
|
|
5419
|
+
for (const entry of entries) {
|
|
5420
|
+
const fullPath = import_node_path3.default.join(dir, entry.name);
|
|
5421
|
+
if (entry.isDirectory()) {
|
|
5422
|
+
yield* walkDirectory(fullPath);
|
|
5423
|
+
} else if (entry.isFile()) {
|
|
5424
|
+
yield fullPath;
|
|
5425
|
+
}
|
|
5426
|
+
}
|
|
5427
|
+
}
|
|
5428
|
+
var import_node_fs2, import_node_path3, import_js_yaml, RESOURCE_CATEGORIES, MAX_NAME_LENGTH, MAX_DESCRIPTION_LENGTH, NAME_PATTERN;
|
|
5429
|
+
var init_parser = __esm({
|
|
5430
|
+
"src/skills/parser.ts"() {
|
|
5431
|
+
"use strict";
|
|
5432
|
+
import_node_fs2 = __toESM(require("fs"), 1);
|
|
5433
|
+
import_node_path3 = __toESM(require("path"), 1);
|
|
5434
|
+
import_js_yaml = __toESM(require("js-yaml"), 1);
|
|
5435
|
+
RESOURCE_CATEGORIES = ["scripts", "references", "assets"];
|
|
5436
|
+
MAX_NAME_LENGTH = 64;
|
|
5437
|
+
MAX_DESCRIPTION_LENGTH = 1024;
|
|
5438
|
+
NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
5439
|
+
}
|
|
5440
|
+
});
|
|
5441
|
+
|
|
5442
|
+
// src/skills/registry.ts
|
|
5443
|
+
var registry_exports = {};
|
|
5444
|
+
__export(registry_exports, {
|
|
5445
|
+
SkillRegistry: () => SkillRegistry
|
|
5446
|
+
});
|
|
5447
|
+
var import_minimatch, DEFAULT_CHAR_BUDGET, SUMMARY_DESCRIPTION_LIMIT, SkillRegistry;
|
|
5448
|
+
var init_registry2 = __esm({
|
|
5449
|
+
"src/skills/registry.ts"() {
|
|
5450
|
+
"use strict";
|
|
5451
|
+
import_minimatch = require("minimatch");
|
|
5452
|
+
DEFAULT_CHAR_BUDGET = 8e3;
|
|
5453
|
+
SUMMARY_DESCRIPTION_LIMIT = 250;
|
|
5454
|
+
SkillRegistry = class _SkillRegistry {
|
|
5455
|
+
skills = /* @__PURE__ */ new Map();
|
|
5456
|
+
/**
|
|
5457
|
+
* Register a skill. Overwrites any existing skill with the same name.
|
|
5458
|
+
*
|
|
5459
|
+
* Unlike GadgetRegistry (which throws on duplicates), SkillRegistry allows
|
|
5460
|
+
* overwriting because skills are loaded from multiple sources with intentional
|
|
5461
|
+
* priority ordering (project > user > default).
|
|
5462
|
+
*/
|
|
5463
|
+
register(skill) {
|
|
5464
|
+
this.skills.set(skill.name.toLowerCase(), skill);
|
|
5465
|
+
}
|
|
5466
|
+
/** Register multiple skills. */
|
|
5467
|
+
registerMany(skills) {
|
|
5468
|
+
for (const skill of skills) {
|
|
5469
|
+
this.register(skill);
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
/** Remove a skill by name (case-insensitive). Returns true if removed. */
|
|
5473
|
+
remove(name) {
|
|
5474
|
+
return this.skills.delete(name.toLowerCase());
|
|
5475
|
+
}
|
|
5476
|
+
/** Remove all registered skills. */
|
|
5477
|
+
clear() {
|
|
5478
|
+
this.skills.clear();
|
|
5479
|
+
}
|
|
5480
|
+
/** Get a skill by name (case-insensitive). */
|
|
5481
|
+
get(name) {
|
|
5482
|
+
return this.skills.get(name.toLowerCase());
|
|
5483
|
+
}
|
|
5484
|
+
/** Check if a skill exists by name (case-insensitive). */
|
|
5485
|
+
has(name) {
|
|
5486
|
+
return this.skills.has(name.toLowerCase());
|
|
5487
|
+
}
|
|
5488
|
+
/** Get all registered skills. */
|
|
5489
|
+
getAll() {
|
|
5490
|
+
return [...this.skills.values()];
|
|
5491
|
+
}
|
|
5492
|
+
/** Get all skill names. */
|
|
5493
|
+
getNames() {
|
|
5494
|
+
return [...this.skills.keys()];
|
|
5495
|
+
}
|
|
5496
|
+
/** Number of registered skills. */
|
|
5497
|
+
get size() {
|
|
5498
|
+
return this.skills.size;
|
|
5499
|
+
}
|
|
5500
|
+
/**
|
|
5501
|
+
* Get skills that are visible to the LLM for auto-triggering.
|
|
5502
|
+
* Excludes skills with disableModelInvocation: true.
|
|
5503
|
+
*/
|
|
5504
|
+
getModelInvocable() {
|
|
5505
|
+
return this.getAll().filter((s) => s.isModelInvocable);
|
|
5506
|
+
}
|
|
5507
|
+
/**
|
|
5508
|
+
* Get skills that the user can invoke via /skill-name.
|
|
5509
|
+
* Excludes skills with userInvocable: false.
|
|
5510
|
+
*/
|
|
5511
|
+
getUserInvocable() {
|
|
5512
|
+
return this.getAll().filter((s) => s.isUserInvocable);
|
|
5513
|
+
}
|
|
5514
|
+
/**
|
|
5515
|
+
* Generate metadata summaries for system prompt injection (Tier 1).
|
|
5516
|
+
*
|
|
5517
|
+
* Each skill contributes a one-line summary: "name — description".
|
|
5518
|
+
* Output is truncated to fit the character budget.
|
|
5519
|
+
*
|
|
5520
|
+
* @param charBudget - Maximum characters for all summaries combined.
|
|
5521
|
+
*/
|
|
5522
|
+
getMetadataSummaries(charBudget = DEFAULT_CHAR_BUDGET) {
|
|
5523
|
+
const invocable = this.getModelInvocable();
|
|
5524
|
+
if (invocable.length === 0) return "";
|
|
5525
|
+
const lines = [];
|
|
5526
|
+
let totalChars = 0;
|
|
5527
|
+
for (const skill of invocable) {
|
|
5528
|
+
const desc = skill.description.length > SUMMARY_DESCRIPTION_LIMIT ? `${skill.description.slice(0, SUMMARY_DESCRIPTION_LIMIT - 3)}...` : skill.description;
|
|
5529
|
+
const line = `- ${skill.name}: ${desc}`;
|
|
5530
|
+
if (totalChars + line.length > charBudget) break;
|
|
5531
|
+
lines.push(line);
|
|
5532
|
+
totalChars += line.length + 1;
|
|
5533
|
+
}
|
|
5534
|
+
return lines.join("\n");
|
|
5535
|
+
}
|
|
5536
|
+
/**
|
|
5537
|
+
* Find skills whose `paths` patterns match a given file path.
|
|
5538
|
+
* Used for auto-activation when the user is working on specific files.
|
|
5539
|
+
*/
|
|
5540
|
+
findByFilePath(filePath) {
|
|
5541
|
+
return this.getModelInvocable().filter((skill) => {
|
|
5542
|
+
const patterns = skill.metadata.paths;
|
|
5543
|
+
if (!patterns || patterns.length === 0) return false;
|
|
5544
|
+
return patterns.some((pattern) => (0, import_minimatch.minimatch)(filePath, pattern));
|
|
5545
|
+
});
|
|
5546
|
+
}
|
|
5547
|
+
/**
|
|
5548
|
+
* Merge another registry into this one.
|
|
5549
|
+
* Skills from the other registry overwrite existing skills with the same name.
|
|
5550
|
+
*/
|
|
5551
|
+
merge(other) {
|
|
5552
|
+
for (const skill of other.getAll()) {
|
|
5553
|
+
this.register(skill);
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
/** Create a registry from an array of skills. */
|
|
5557
|
+
static from(skills) {
|
|
5558
|
+
const registry = new _SkillRegistry();
|
|
5559
|
+
registry.registerMany(skills);
|
|
5560
|
+
return registry;
|
|
5561
|
+
}
|
|
5562
|
+
};
|
|
5563
|
+
}
|
|
5564
|
+
});
|
|
5565
|
+
|
|
5566
|
+
// src/skills/skill.ts
|
|
5567
|
+
var import_promises2, Skill;
|
|
5568
|
+
var init_skill = __esm({
|
|
5569
|
+
"src/skills/skill.ts"() {
|
|
5570
|
+
"use strict";
|
|
5571
|
+
import_promises2 = __toESM(require("fs/promises"), 1);
|
|
5572
|
+
init_activation();
|
|
5573
|
+
init_parser();
|
|
5574
|
+
Skill = class _Skill {
|
|
5575
|
+
metadata;
|
|
5576
|
+
sourcePath;
|
|
5577
|
+
sourceDir;
|
|
5578
|
+
source;
|
|
5579
|
+
_instructions;
|
|
5580
|
+
_resources;
|
|
5581
|
+
_resourceCache = /* @__PURE__ */ new Map();
|
|
5582
|
+
_resourceLoading = /* @__PURE__ */ new Map();
|
|
5583
|
+
constructor(parsed) {
|
|
5584
|
+
this.metadata = parsed.metadata;
|
|
5585
|
+
this.sourcePath = parsed.sourcePath;
|
|
5586
|
+
this.sourceDir = parsed.sourceDir;
|
|
5587
|
+
this.source = parsed.source;
|
|
5588
|
+
this._instructions = parsed.instructions;
|
|
5589
|
+
this._resources = parsed.resources;
|
|
5590
|
+
}
|
|
5591
|
+
/** Skill name for registry lookup. */
|
|
5592
|
+
get name() {
|
|
5593
|
+
return this.metadata.name;
|
|
5594
|
+
}
|
|
5595
|
+
/** Skill description for LLM matching. */
|
|
5596
|
+
get description() {
|
|
5597
|
+
return this.metadata.description;
|
|
5598
|
+
}
|
|
5599
|
+
/** Whether the LLM can auto-trigger this skill. */
|
|
5600
|
+
get isModelInvocable() {
|
|
5601
|
+
return this.metadata.disableModelInvocation !== true;
|
|
5602
|
+
}
|
|
5603
|
+
/** Whether the user can invoke this skill via /skill-name. */
|
|
5604
|
+
get isUserInvocable() {
|
|
5605
|
+
return this.metadata.userInvocable !== false;
|
|
5606
|
+
}
|
|
5607
|
+
/**
|
|
5608
|
+
* Load and cache Tier 2 instructions.
|
|
5609
|
+
* If instructions were loaded during parsing, returns the cached value.
|
|
5610
|
+
*/
|
|
5611
|
+
async getInstructions() {
|
|
5612
|
+
if (this._instructions !== null) return this._instructions;
|
|
5613
|
+
const content = await import_promises2.default.readFile(this.sourcePath, "utf-8");
|
|
5614
|
+
const { body } = parseFrontmatter(content);
|
|
5615
|
+
this._instructions = body;
|
|
5616
|
+
return body;
|
|
5617
|
+
}
|
|
5618
|
+
/**
|
|
5619
|
+
* List Tier 3 resources.
|
|
5620
|
+
* Resources are discovered at parse time but content is loaded on demand.
|
|
5621
|
+
*/
|
|
5622
|
+
getResources() {
|
|
5623
|
+
return this._resources;
|
|
5624
|
+
}
|
|
5625
|
+
/**
|
|
5626
|
+
* Load a specific Tier 3 resource by relative path.
|
|
5627
|
+
* Results are cached for the lifetime of this Skill instance.
|
|
5628
|
+
* Concurrent calls for the same resource share a single read.
|
|
5629
|
+
*/
|
|
5630
|
+
async getResource(relativePath) {
|
|
5631
|
+
if (relativePath.includes("..")) {
|
|
5632
|
+
throw new Error(`Invalid resource path (path traversal): ${relativePath}`);
|
|
5633
|
+
}
|
|
5634
|
+
const cached = this._resourceCache.get(relativePath);
|
|
5635
|
+
if (cached !== void 0) return cached;
|
|
5636
|
+
const existing = this._resourceLoading.get(relativePath);
|
|
5637
|
+
if (existing) return existing;
|
|
5638
|
+
const resource = this._resources.find((r) => r.relativePath === relativePath);
|
|
5639
|
+
if (!resource) {
|
|
5640
|
+
throw new Error(`Resource not found: ${relativePath} in skill ${this.name}`);
|
|
5641
|
+
}
|
|
5642
|
+
const loadPromise = import_promises2.default.readFile(resource.absolutePath, "utf-8").then(
|
|
5643
|
+
(content) => {
|
|
5644
|
+
this._resourceCache.set(relativePath, content);
|
|
5645
|
+
this._resourceLoading.delete(relativePath);
|
|
5646
|
+
return content;
|
|
5647
|
+
},
|
|
5648
|
+
(error) => {
|
|
5649
|
+
this._resourceLoading.delete(relativePath);
|
|
5650
|
+
throw new Error(
|
|
5651
|
+
`Failed to load resource ${relativePath} in skill ${this.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
5652
|
+
);
|
|
5653
|
+
}
|
|
5654
|
+
);
|
|
5655
|
+
this._resourceLoading.set(relativePath, loadPromise);
|
|
5656
|
+
return loadPromise;
|
|
5657
|
+
}
|
|
5658
|
+
/**
|
|
5659
|
+
* Activate this skill with optional arguments.
|
|
5660
|
+
*
|
|
5661
|
+
* Performs:
|
|
5662
|
+
* 1. Variable substitution (${SKILL_DIR}, etc.)
|
|
5663
|
+
* 2. Argument substitution ($ARGUMENTS, $0, $1)
|
|
5664
|
+
* 3. Shell preprocessing (!`command`)
|
|
5665
|
+
* 4. Resource loading (if eagerResources is true)
|
|
5666
|
+
*/
|
|
5667
|
+
async activate(options) {
|
|
5668
|
+
const instructions = await this.getInstructions();
|
|
5669
|
+
const resolvedInstructions = resolveInstructions(instructions, {
|
|
5670
|
+
arguments: options?.arguments,
|
|
5671
|
+
variables: {
|
|
5672
|
+
SKILL_DIR: this.sourceDir,
|
|
5673
|
+
CLAUDE_SKILL_DIR: this.sourceDir
|
|
5674
|
+
},
|
|
5675
|
+
cwd: options?.cwd ?? this.sourceDir,
|
|
5676
|
+
shell: this.metadata.shell,
|
|
5677
|
+
enableShellPreprocessing: options?.enableShellPreprocessing,
|
|
5678
|
+
shellTimeoutMs: options?.shellTimeoutMs
|
|
5679
|
+
});
|
|
5680
|
+
const loadedResources = /* @__PURE__ */ new Map();
|
|
5681
|
+
if (options?.eagerResources) {
|
|
5682
|
+
for (const resource of this._resources) {
|
|
5683
|
+
const content = await this.getResource(resource.relativePath);
|
|
5684
|
+
loadedResources.set(resource.relativePath, content);
|
|
5685
|
+
}
|
|
5686
|
+
}
|
|
5687
|
+
return {
|
|
5688
|
+
skillName: this.name,
|
|
5689
|
+
resolvedInstructions,
|
|
5690
|
+
gadgets: [],
|
|
5691
|
+
// Gadgets are resolved by the CLI layer
|
|
5692
|
+
loadedResources
|
|
5693
|
+
};
|
|
5694
|
+
}
|
|
5695
|
+
/**
|
|
5696
|
+
* Create a Skill from a SKILL.md content string.
|
|
5697
|
+
* Useful for testing or dynamic skill creation.
|
|
5698
|
+
*/
|
|
5699
|
+
static fromContent(content, sourcePath, source = { type: "directory", path: sourcePath }) {
|
|
5700
|
+
const parsed = parseSkillContent(content, sourcePath, source, true);
|
|
5701
|
+
return new _Skill(parsed);
|
|
5702
|
+
}
|
|
5703
|
+
};
|
|
5704
|
+
}
|
|
5705
|
+
});
|
|
5706
|
+
|
|
5707
|
+
// src/skills/loader.ts
|
|
5708
|
+
function loadSkillsFromDirectory(dir, source, onWarning) {
|
|
5709
|
+
if (!import_node_fs3.default.existsSync(dir)) return [];
|
|
5710
|
+
const stat = import_node_fs3.default.statSync(dir);
|
|
5711
|
+
if (!stat.isDirectory()) return [];
|
|
5712
|
+
const skills = [];
|
|
5713
|
+
scanForSkills(dir, source, skills, onWarning);
|
|
5714
|
+
return skills;
|
|
5715
|
+
}
|
|
5716
|
+
function discoverSkills(options) {
|
|
5717
|
+
const registry = new SkillRegistry();
|
|
5718
|
+
const userSkillsDir = options?.userDir ?? import_node_path4.default.join(import_node_os2.default.homedir(), CONFIG_DIR_NAME, SKILLS_DIR_NAME);
|
|
5719
|
+
const userSkills = loadSkillsFromDirectory(userSkillsDir, {
|
|
5720
|
+
type: "user",
|
|
5721
|
+
path: userSkillsDir
|
|
5722
|
+
});
|
|
5723
|
+
registry.registerMany(userSkills);
|
|
5724
|
+
if (options?.projectDir) {
|
|
5725
|
+
const projectSkillsDir = import_node_path4.default.join(options.projectDir, CONFIG_DIR_NAME, SKILLS_DIR_NAME);
|
|
5726
|
+
const projectSkills = loadSkillsFromDirectory(projectSkillsDir, {
|
|
5727
|
+
type: "project",
|
|
5728
|
+
path: projectSkillsDir
|
|
5729
|
+
});
|
|
5730
|
+
registry.registerMany(projectSkills);
|
|
5731
|
+
}
|
|
5732
|
+
if (options?.additionalDirs) {
|
|
5733
|
+
for (const dir of options.additionalDirs) {
|
|
5734
|
+
const resolvedDir = dir.startsWith("~") ? import_node_path4.default.join(import_node_os2.default.homedir(), dir.slice(1)) : dir;
|
|
5735
|
+
const skills = loadSkillsFromDirectory(resolvedDir, {
|
|
5736
|
+
type: "directory",
|
|
5737
|
+
path: resolvedDir
|
|
5738
|
+
});
|
|
5739
|
+
registry.registerMany(skills);
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
return registry;
|
|
5743
|
+
}
|
|
5744
|
+
function scanForSkills(dir, source, results, onWarning) {
|
|
5745
|
+
let entries;
|
|
5746
|
+
try {
|
|
5747
|
+
entries = import_node_fs3.default.readdirSync(dir, { withFileTypes: true });
|
|
5748
|
+
} catch (error) {
|
|
5749
|
+
onWarning?.(
|
|
5750
|
+
`Cannot read skill directory ${dir}: ${error instanceof Error ? error.message : String(error)}`
|
|
5751
|
+
);
|
|
5752
|
+
return;
|
|
5753
|
+
}
|
|
5754
|
+
const skillMdPath = import_node_path4.default.join(dir, "SKILL.md");
|
|
5755
|
+
if (import_node_fs3.default.existsSync(skillMdPath)) {
|
|
5756
|
+
try {
|
|
5757
|
+
const parsed = parseSkillFile(skillMdPath, source, false);
|
|
5758
|
+
results.push(new Skill(parsed));
|
|
5759
|
+
} catch (error) {
|
|
5760
|
+
onWarning?.(
|
|
5761
|
+
`Failed to parse ${skillMdPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
5762
|
+
);
|
|
5763
|
+
}
|
|
5764
|
+
return;
|
|
5765
|
+
}
|
|
5766
|
+
for (const entry of entries) {
|
|
5767
|
+
if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
5768
|
+
scanForSkills(import_node_path4.default.join(dir, entry.name), source, results, onWarning);
|
|
5769
|
+
}
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
var import_node_fs3, import_node_os2, import_node_path4, SKILLS_DIR_NAME, CONFIG_DIR_NAME;
|
|
5773
|
+
var init_loader = __esm({
|
|
5774
|
+
"src/skills/loader.ts"() {
|
|
5775
|
+
"use strict";
|
|
5776
|
+
import_node_fs3 = __toESM(require("fs"), 1);
|
|
5777
|
+
import_node_os2 = __toESM(require("os"), 1);
|
|
5778
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
5779
|
+
init_parser();
|
|
5780
|
+
init_registry2();
|
|
5781
|
+
init_skill();
|
|
5782
|
+
SKILLS_DIR_NAME = "skills";
|
|
5783
|
+
CONFIG_DIR_NAME = ".llmist";
|
|
5784
|
+
}
|
|
5785
|
+
});
|
|
5786
|
+
|
|
5787
|
+
// src/skills/use-skill-gadget.ts
|
|
5788
|
+
function createUseSkillGadget(registry) {
|
|
5789
|
+
const summaries = registry.getMetadataSummaries();
|
|
5790
|
+
const skillNames = registry.getModelInvocable().map((s) => s.name);
|
|
5791
|
+
const description = [
|
|
5792
|
+
"Activate a skill to get specialized instructions for a task.",
|
|
5793
|
+
"Available skills:",
|
|
5794
|
+
summaries
|
|
5795
|
+
].join("\n");
|
|
5796
|
+
return createGadget({
|
|
5797
|
+
name: USE_SKILL_GADGET_NAME,
|
|
5798
|
+
description,
|
|
5799
|
+
schema: import_zod2.z.object({
|
|
5800
|
+
skill: import_zod2.z.enum(skillNames).describe("Name of the skill to activate"),
|
|
5801
|
+
arguments: import_zod2.z.string().optional().describe("Arguments for the skill (e.g., a filename, issue number, or search query)")
|
|
5802
|
+
}),
|
|
5803
|
+
execute: async ({ skill: skillName, arguments: args }) => {
|
|
5804
|
+
const skill = registry.get(skillName);
|
|
5805
|
+
if (!skill) {
|
|
5806
|
+
return `Unknown skill: "${skillName}". Available skills: ${skillNames.join(", ")}`;
|
|
5807
|
+
}
|
|
5808
|
+
const activation = await skill.activate({
|
|
5809
|
+
arguments: args,
|
|
5810
|
+
cwd: process.cwd()
|
|
5811
|
+
});
|
|
5812
|
+
return activation.resolvedInstructions;
|
|
5813
|
+
}
|
|
5814
|
+
});
|
|
5815
|
+
}
|
|
5816
|
+
var import_zod2, USE_SKILL_GADGET_NAME;
|
|
5817
|
+
var init_use_skill_gadget = __esm({
|
|
5818
|
+
"src/skills/use-skill-gadget.ts"() {
|
|
5819
|
+
"use strict";
|
|
5820
|
+
import_zod2 = require("zod");
|
|
5821
|
+
init_create_gadget();
|
|
5822
|
+
USE_SKILL_GADGET_NAME = "UseSkill";
|
|
5823
|
+
}
|
|
5824
|
+
});
|
|
5825
|
+
|
|
5206
5826
|
// src/agent/builder-utils.ts
|
|
5207
5827
|
function formatGadgetCall(gadgetName, invocationId, parameters, prefixes) {
|
|
5208
5828
|
const startPrefix = prefixes?.start ?? GADGET_START_PREFIX;
|
|
@@ -5336,7 +5956,7 @@ function resolveLoggingDirectory(state, baseDirectory, counterPadding, subagentC
|
|
|
5336
5956
|
if (!fullPath) {
|
|
5337
5957
|
const chronoNumber = getNextCounter(state, parentDir);
|
|
5338
5958
|
const subdirName = `${formatCallNumber(chronoNumber, counterPadding)}-${parentGadgetInvocationId}`;
|
|
5339
|
-
fullPath = (0,
|
|
5959
|
+
fullPath = (0, import_node_path5.join)(parentDir, subdirName);
|
|
5340
5960
|
state.subagentDirectories.set(subagentKey, fullPath);
|
|
5341
5961
|
}
|
|
5342
5962
|
state.activeDirectoryByContext.set(contextKey, fullPath);
|
|
@@ -5355,8 +5975,8 @@ function formatCallNumber(n, padding = 4) {
|
|
|
5355
5975
|
return n.toString().padStart(padding, "0");
|
|
5356
5976
|
}
|
|
5357
5977
|
async function writeLogFile(dir, filename, content) {
|
|
5358
|
-
await (0,
|
|
5359
|
-
await (0,
|
|
5978
|
+
await (0, import_promises3.mkdir)(dir, { recursive: true });
|
|
5979
|
+
await (0, import_promises3.writeFile)((0, import_node_path5.join)(dir, filename), content, "utf-8");
|
|
5360
5980
|
}
|
|
5361
5981
|
function createFileLoggingHooks(options, state = getDefaultState()) {
|
|
5362
5982
|
const {
|
|
@@ -5366,7 +5986,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
|
|
|
5366
5986
|
formatRequest = formatLlmRequest,
|
|
5367
5987
|
onFileWritten
|
|
5368
5988
|
} = options;
|
|
5369
|
-
const baseDirectory = (0,
|
|
5989
|
+
const baseDirectory = (0, import_node_path5.resolve)(options.directory);
|
|
5370
5990
|
if (!state.counters.has(baseDirectory)) {
|
|
5371
5991
|
state.counters.set(baseDirectory, startingCounter - 1);
|
|
5372
5992
|
}
|
|
@@ -5394,7 +6014,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
|
|
|
5394
6014
|
await writeLogFile(currentDirectory, filename, content);
|
|
5395
6015
|
if (onFileWritten) {
|
|
5396
6016
|
onFileWritten({
|
|
5397
|
-
filePath: (0,
|
|
6017
|
+
filePath: (0, import_node_path5.join)(currentDirectory, filename),
|
|
5398
6018
|
type: "request",
|
|
5399
6019
|
callNumber: currentCallNumber,
|
|
5400
6020
|
contentLength: content.length,
|
|
@@ -5423,7 +6043,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
|
|
|
5423
6043
|
await writeLogFile(currentDirectory, filename, content);
|
|
5424
6044
|
if (onFileWritten) {
|
|
5425
6045
|
onFileWritten({
|
|
5426
|
-
filePath: (0,
|
|
6046
|
+
filePath: (0, import_node_path5.join)(currentDirectory, filename),
|
|
5427
6047
|
type: "response",
|
|
5428
6048
|
callNumber: currentCallNumber,
|
|
5429
6049
|
contentLength: content.length,
|
|
@@ -5445,12 +6065,12 @@ function getEnvFileLoggingHooks() {
|
|
|
5445
6065
|
}
|
|
5446
6066
|
return createFileLoggingHooks({ directory });
|
|
5447
6067
|
}
|
|
5448
|
-
var
|
|
6068
|
+
var import_promises3, import_node_path5, defaultState, ENV_LOG_RAW_DIRECTORY;
|
|
5449
6069
|
var init_file_logging = __esm({
|
|
5450
6070
|
"src/agent/file-logging.ts"() {
|
|
5451
6071
|
"use strict";
|
|
5452
|
-
|
|
5453
|
-
|
|
6072
|
+
import_promises3 = require("fs/promises");
|
|
6073
|
+
import_node_path5 = require("path");
|
|
5454
6074
|
init_messages();
|
|
5455
6075
|
ENV_LOG_RAW_DIRECTORY = "LLMIST_LOG_RAW_DIRECTORY";
|
|
5456
6076
|
}
|
|
@@ -12207,6 +12827,10 @@ var init_builder = __esm({
|
|
|
12207
12827
|
"use strict";
|
|
12208
12828
|
init_model_shortcuts();
|
|
12209
12829
|
init_registry();
|
|
12830
|
+
init_activation();
|
|
12831
|
+
init_loader();
|
|
12832
|
+
init_parser();
|
|
12833
|
+
init_use_skill_gadget();
|
|
12210
12834
|
init_agent();
|
|
12211
12835
|
init_agent_internal_key();
|
|
12212
12836
|
init_builder_utils();
|
|
@@ -12218,12 +12842,14 @@ var init_builder = __esm({
|
|
|
12218
12842
|
retry;
|
|
12219
12843
|
subagents;
|
|
12220
12844
|
policies;
|
|
12845
|
+
skills;
|
|
12221
12846
|
constructor(client) {
|
|
12222
12847
|
this.core = { client, initialMessages: [] };
|
|
12223
12848
|
this.gadgets = { gadgets: [] };
|
|
12224
12849
|
this.retry = {};
|
|
12225
12850
|
this.subagents = {};
|
|
12226
12851
|
this.policies = {};
|
|
12852
|
+
this.skills = { preActivated: [], skillDirs: [] };
|
|
12227
12853
|
}
|
|
12228
12854
|
/** Set the model to use. Supports aliases like "sonnet", "flash". */
|
|
12229
12855
|
withModel(model) {
|
|
@@ -12360,6 +12986,38 @@ var init_builder = __esm({
|
|
|
12360
12986
|
this.policies.compactionConfig = { enabled: false };
|
|
12361
12987
|
return this;
|
|
12362
12988
|
}
|
|
12989
|
+
// ─── Skills ──────────────────────────────────────────────────────────────────
|
|
12990
|
+
/** Register a skill registry for this agent. */
|
|
12991
|
+
withSkills(registry) {
|
|
12992
|
+
this.skills.registry = registry;
|
|
12993
|
+
return this;
|
|
12994
|
+
}
|
|
12995
|
+
/**
|
|
12996
|
+
* Pre-activate a specific skill before the agent starts.
|
|
12997
|
+
* Instructions are injected into the system prompt.
|
|
12998
|
+
*
|
|
12999
|
+
* Note: each call replaces (not appends) the pre-activated skill for that name.
|
|
13000
|
+
* This is safe for REPL loops where the same builder is reused.
|
|
13001
|
+
*/
|
|
13002
|
+
withSkill(name, args) {
|
|
13003
|
+
const existing = this.skills.preActivated.findIndex((s) => s.name === name);
|
|
13004
|
+
if (existing !== -1) {
|
|
13005
|
+
this.skills.preActivated[existing] = { name, args };
|
|
13006
|
+
} else {
|
|
13007
|
+
this.skills.preActivated.push({ name, args });
|
|
13008
|
+
}
|
|
13009
|
+
return this;
|
|
13010
|
+
}
|
|
13011
|
+
/** Clear all pre-activated skills. Call between REPL iterations. */
|
|
13012
|
+
clearPreActivatedSkills() {
|
|
13013
|
+
this.skills.preActivated = [];
|
|
13014
|
+
return this;
|
|
13015
|
+
}
|
|
13016
|
+
/** Add a directory to scan for skills. */
|
|
13017
|
+
withSkillsFrom(dir) {
|
|
13018
|
+
this.skills.skillDirs.push(dir);
|
|
13019
|
+
return this;
|
|
13020
|
+
}
|
|
12363
13021
|
/** Configure retry behavior for LLM API calls. */
|
|
12364
13022
|
withRetry(config) {
|
|
12365
13023
|
this.retry.retryConfig = { ...config, enabled: config.enabled ?? true };
|
|
@@ -12451,16 +13109,75 @@ var init_builder = __esm({
|
|
|
12451
13109
|
composeHooks() {
|
|
12452
13110
|
return HookComposer.compose(this.core.hooks, this.core.trailingMessage);
|
|
12453
13111
|
}
|
|
13112
|
+
resolveSkillRegistry() {
|
|
13113
|
+
if (this.skills.registry) {
|
|
13114
|
+
if (this.skills.skillDirs.length > 0) {
|
|
13115
|
+
for (const dir of this.skills.skillDirs) {
|
|
13116
|
+
const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
|
|
13117
|
+
this.skills.registry.registerMany(skills);
|
|
13118
|
+
}
|
|
13119
|
+
}
|
|
13120
|
+
return this.skills.registry;
|
|
13121
|
+
}
|
|
13122
|
+
if (this.skills.skillDirs.length > 0) {
|
|
13123
|
+
const { SkillRegistry: SR } = (init_registry2(), __toCommonJS(registry_exports));
|
|
13124
|
+
const reg = new SR();
|
|
13125
|
+
for (const dir of this.skills.skillDirs) {
|
|
13126
|
+
const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
|
|
13127
|
+
reg.registerMany(skills);
|
|
13128
|
+
}
|
|
13129
|
+
return reg;
|
|
13130
|
+
}
|
|
13131
|
+
return void 0;
|
|
13132
|
+
}
|
|
13133
|
+
/**
|
|
13134
|
+
* Resolve pre-activated skill instructions synchronously.
|
|
13135
|
+
* Reads SKILL.md from disk via readFileSync (skills are local files).
|
|
13136
|
+
*/
|
|
13137
|
+
resolvePreActivatedInstructions(skillRegistry) {
|
|
13138
|
+
if (this.skills.preActivated.length === 0) return void 0;
|
|
13139
|
+
const fs4 = require("fs");
|
|
13140
|
+
const blocks = [];
|
|
13141
|
+
for (const { name, args } of this.skills.preActivated) {
|
|
13142
|
+
const skill = skillRegistry.get(name);
|
|
13143
|
+
if (!skill) continue;
|
|
13144
|
+
const content = fs4.readFileSync(skill.sourcePath, "utf-8");
|
|
13145
|
+
const { body } = parseFrontmatter(content);
|
|
13146
|
+
const resolved = resolveInstructions(body, {
|
|
13147
|
+
arguments: args,
|
|
13148
|
+
variables: { SKILL_DIR: skill.sourceDir, CLAUDE_SKILL_DIR: skill.sourceDir },
|
|
13149
|
+
cwd: skill.sourceDir,
|
|
13150
|
+
shell: skill.metadata.shell
|
|
13151
|
+
});
|
|
13152
|
+
blocks.push(`## Skill: ${name}
|
|
13153
|
+
|
|
13154
|
+
${resolved}`);
|
|
13155
|
+
}
|
|
13156
|
+
return blocks.length > 0 ? blocks.join("\n\n---\n\n") : void 0;
|
|
13157
|
+
}
|
|
12454
13158
|
buildAgentOptions(userPrompt) {
|
|
12455
13159
|
if (!this.core.client) {
|
|
12456
13160
|
const { LLMist: LLMistClass } = (init_client(), __toCommonJS(client_exports));
|
|
12457
13161
|
this.core.client = new LLMistClass();
|
|
12458
13162
|
}
|
|
12459
13163
|
const registry = GadgetRegistry.from(this.gadgets.gadgets);
|
|
13164
|
+
let systemPrompt = this.core.systemPrompt;
|
|
13165
|
+
const skillRegistry = this.resolveSkillRegistry();
|
|
13166
|
+
if (skillRegistry && skillRegistry.size > 0) {
|
|
13167
|
+
if (skillRegistry.getModelInvocable().length > 0) {
|
|
13168
|
+
registry.registerByClass(createUseSkillGadget(skillRegistry));
|
|
13169
|
+
}
|
|
13170
|
+
const preActivatedBlock = this.resolvePreActivatedInstructions(skillRegistry);
|
|
13171
|
+
if (preActivatedBlock) {
|
|
13172
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
13173
|
+
|
|
13174
|
+
${preActivatedBlock}` : preActivatedBlock;
|
|
13175
|
+
}
|
|
13176
|
+
}
|
|
12460
13177
|
return {
|
|
12461
13178
|
client: this.core.client,
|
|
12462
13179
|
model: this.core.model ?? "openai:gpt-5-nano",
|
|
12463
|
-
systemPrompt
|
|
13180
|
+
systemPrompt,
|
|
12464
13181
|
userPrompt,
|
|
12465
13182
|
registry,
|
|
12466
13183
|
maxIterations: this.core.maxIterations,
|
|
@@ -13145,8 +13862,8 @@ var init_error_formatter = __esm({
|
|
|
13145
13862
|
const parts = [];
|
|
13146
13863
|
parts.push(`Error: Invalid parameters for '${gadgetName}':`);
|
|
13147
13864
|
for (const issue of zodError.issues) {
|
|
13148
|
-
const
|
|
13149
|
-
parts.push(` - ${
|
|
13865
|
+
const path3 = issue.path.join(".") || "root";
|
|
13866
|
+
parts.push(` - ${path3}: ${issue.message}`);
|
|
13150
13867
|
}
|
|
13151
13868
|
parts.push("");
|
|
13152
13869
|
parts.push("Gadget Usage:");
|
|
@@ -13211,7 +13928,7 @@ function stripMarkdownFences(content) {
|
|
|
13211
13928
|
return cleaned.trim();
|
|
13212
13929
|
}
|
|
13213
13930
|
var globalInvocationCounter, GadgetCallParser;
|
|
13214
|
-
var
|
|
13931
|
+
var init_parser2 = __esm({
|
|
13215
13932
|
"src/gadgets/parser.ts"() {
|
|
13216
13933
|
"use strict";
|
|
13217
13934
|
init_constants();
|
|
@@ -13247,8 +13964,9 @@ var init_parser = __esm({
|
|
|
13247
13964
|
* - `GadgetName` - Auto-generate ID, no dependencies
|
|
13248
13965
|
* - `GadgetName:my_id` - Explicit ID, no dependencies
|
|
13249
13966
|
* - `GadgetName:my_id:dep1,dep2` - Explicit ID with dependencies
|
|
13967
|
+
* - `GadgetName:my_id:dep1:dep2:dep3` - Colons treated as dep separators (LLM resilience)
|
|
13250
13968
|
*
|
|
13251
|
-
* Dependencies
|
|
13969
|
+
* Dependencies can be comma-separated or colon-separated invocation IDs.
|
|
13252
13970
|
*/
|
|
13253
13971
|
parseInvocationMetadata(headerLine) {
|
|
13254
13972
|
const parts = headerLine.split(":");
|
|
@@ -13265,7 +13983,12 @@ var init_parser = __esm({
|
|
|
13265
13983
|
dependencies: []
|
|
13266
13984
|
};
|
|
13267
13985
|
} else {
|
|
13268
|
-
const
|
|
13986
|
+
const depsRaw = parts.slice(2).join(",");
|
|
13987
|
+
const deps = [
|
|
13988
|
+
...new Set(
|
|
13989
|
+
depsRaw.split(",").map((d) => d.trim()).filter((d) => d.length > 0)
|
|
13990
|
+
)
|
|
13991
|
+
];
|
|
13269
13992
|
return {
|
|
13270
13993
|
gadgetName: parts[0],
|
|
13271
13994
|
invocationId: parts[1].trim(),
|
|
@@ -13423,15 +14146,15 @@ function getHostExportsInternal() {
|
|
|
13423
14146
|
createGadget,
|
|
13424
14147
|
ExecutionTree,
|
|
13425
14148
|
LLMist,
|
|
13426
|
-
z:
|
|
14149
|
+
z: import_zod3.z
|
|
13427
14150
|
};
|
|
13428
14151
|
}
|
|
13429
|
-
var import_fast_deep_equal,
|
|
14152
|
+
var import_fast_deep_equal, import_zod3, GadgetExecutor;
|
|
13430
14153
|
var init_executor = __esm({
|
|
13431
14154
|
"src/gadgets/executor.ts"() {
|
|
13432
14155
|
"use strict";
|
|
13433
14156
|
import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
|
|
13434
|
-
|
|
14157
|
+
import_zod3 = require("zod");
|
|
13435
14158
|
init_builder();
|
|
13436
14159
|
init_hook_utils();
|
|
13437
14160
|
init_client();
|
|
@@ -13443,7 +14166,7 @@ var init_executor = __esm({
|
|
|
13443
14166
|
init_create_gadget();
|
|
13444
14167
|
init_error_formatter();
|
|
13445
14168
|
init_exceptions();
|
|
13446
|
-
|
|
14169
|
+
init_parser2();
|
|
13447
14170
|
init_typed_gadget();
|
|
13448
14171
|
GadgetExecutor = class {
|
|
13449
14172
|
registry;
|
|
@@ -13838,6 +14561,8 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
13838
14561
|
concurrencyQueue = /* @__PURE__ */ new Map();
|
|
13839
14562
|
/** All active gadget promises, keyed by invocationId */
|
|
13840
14563
|
inFlightExecutions = /* @__PURE__ */ new Map();
|
|
14564
|
+
/** Gadget name for each in-flight invocationId (for timeout event emission) */
|
|
14565
|
+
inFlightGadgetNames = /* @__PURE__ */ new Map();
|
|
13841
14566
|
/** Queue of exclusive gadgets deferred until in-flight gadgets complete */
|
|
13842
14567
|
exclusiveQueue = [];
|
|
13843
14568
|
constructor(options) {
|
|
@@ -13965,6 +14690,7 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
13965
14690
|
const currentCount = this.activeCountByGadget.get(gadgetName) ?? 0;
|
|
13966
14691
|
this.activeCountByGadget.set(gadgetName, currentCount + 1);
|
|
13967
14692
|
this.inFlightExecutions.set(invocationId, promise);
|
|
14693
|
+
this.inFlightGadgetNames.set(invocationId, gadgetName);
|
|
13968
14694
|
}
|
|
13969
14695
|
/**
|
|
13970
14696
|
* Called when a gadget execution completes.
|
|
@@ -14008,11 +14734,25 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
14008
14734
|
this.exclusiveQueue.push(call);
|
|
14009
14735
|
}
|
|
14010
14736
|
/**
|
|
14011
|
-
* Clear
|
|
14012
|
-
* Called after
|
|
14737
|
+
* Clear all in-flight tracking state.
|
|
14738
|
+
* Called after all promises have completed, or on force-timeout.
|
|
14739
|
+
* Also clears active gadget counts to prevent stale state when
|
|
14740
|
+
* hanging promises eventually resolve into the void.
|
|
14013
14741
|
*/
|
|
14014
14742
|
clearInFlight() {
|
|
14015
14743
|
this.inFlightExecutions.clear();
|
|
14744
|
+
this.inFlightGadgetNames.clear();
|
|
14745
|
+
this.activeCountByGadget.clear();
|
|
14746
|
+
}
|
|
14747
|
+
/**
|
|
14748
|
+
* Get metadata for all currently in-flight executions.
|
|
14749
|
+
* Used by the dispatcher to emit skip events when the in-flight timeout fires.
|
|
14750
|
+
*/
|
|
14751
|
+
getInFlightEntries() {
|
|
14752
|
+
return Array.from(this.inFlightGadgetNames.entries()).map(([invocationId, gadgetName]) => ({
|
|
14753
|
+
invocationId,
|
|
14754
|
+
gadgetName
|
|
14755
|
+
}));
|
|
14016
14756
|
}
|
|
14017
14757
|
// ==========================================================================
|
|
14018
14758
|
// Waiting
|
|
@@ -14337,6 +15077,7 @@ var init_gadget_dispatcher = __esm({
|
|
|
14337
15077
|
logger;
|
|
14338
15078
|
pushToQueue;
|
|
14339
15079
|
drainQueue;
|
|
15080
|
+
inFlightTimeoutMs;
|
|
14340
15081
|
constructor(options) {
|
|
14341
15082
|
this.iteration = options.iteration;
|
|
14342
15083
|
this.hookLifecycle = options.hookLifecycle;
|
|
@@ -14351,6 +15092,7 @@ var init_gadget_dispatcher = __esm({
|
|
|
14351
15092
|
this.logger = options.logger ?? createLogger({ name: "llmist:gadget-dispatcher" });
|
|
14352
15093
|
this.pushToQueue = options.pushToQueue;
|
|
14353
15094
|
this.drainQueue = options.drainQueue;
|
|
15095
|
+
this.inFlightTimeoutMs = options.inFlightTimeoutMs ?? 3e5;
|
|
14354
15096
|
}
|
|
14355
15097
|
// ==========================================================================
|
|
14356
15098
|
// Primary dispatch entry point
|
|
@@ -14382,39 +15124,54 @@ var init_gadget_dispatcher = __esm({
|
|
|
14382
15124
|
parentId: this.parentNodeId
|
|
14383
15125
|
});
|
|
14384
15126
|
}
|
|
15127
|
+
let effectiveCall = call;
|
|
14385
15128
|
if (call.dependencies.length > 0) {
|
|
14386
|
-
|
|
14387
|
-
|
|
15129
|
+
const selfRefs = [];
|
|
15130
|
+
const validDeps = [];
|
|
15131
|
+
for (const dep of call.dependencies) {
|
|
15132
|
+
(dep === call.invocationId ? selfRefs : validDeps).push(dep);
|
|
15133
|
+
}
|
|
15134
|
+
if (selfRefs.length > 0) {
|
|
15135
|
+
this.logger.warn("Filtering self-referential dependencies", {
|
|
14388
15136
|
gadgetName: call.gadgetName,
|
|
14389
|
-
invocationId: call.invocationId
|
|
15137
|
+
invocationId: call.invocationId,
|
|
15138
|
+
removedSelfRefs: selfRefs,
|
|
15139
|
+
remainingDeps: validDeps
|
|
14390
15140
|
});
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
15141
|
+
effectiveCall = { ...call, dependencies: validDeps };
|
|
15142
|
+
if (validDeps.length === 0) {
|
|
15143
|
+
const errorMessage = `Gadget "${call.invocationId}" cannot depend on itself (self-referential dependency)`;
|
|
15144
|
+
for await (const evt of this.emitGadgetSkipEvents(
|
|
15145
|
+
effectiveCall,
|
|
15146
|
+
call.invocationId,
|
|
15147
|
+
errorMessage
|
|
15148
|
+
)) {
|
|
15149
|
+
yield evt;
|
|
15150
|
+
}
|
|
15151
|
+
return;
|
|
14394
15152
|
}
|
|
14395
|
-
return;
|
|
14396
15153
|
}
|
|
14397
|
-
const failedDep = this.dependencyResolver.getFailedDependency(
|
|
15154
|
+
const failedDep = this.dependencyResolver.getFailedDependency(effectiveCall);
|
|
14398
15155
|
if (failedDep) {
|
|
14399
|
-
const skipEvents = await this.handleFailedDependency(
|
|
15156
|
+
const skipEvents = await this.handleFailedDependency(effectiveCall, failedDep);
|
|
14400
15157
|
for (const evt of skipEvents) {
|
|
14401
15158
|
yield evt;
|
|
14402
15159
|
}
|
|
14403
15160
|
return;
|
|
14404
15161
|
}
|
|
14405
|
-
if (!this.dependencyResolver.isAllSatisfied(
|
|
14406
|
-
const unsatisfied =
|
|
15162
|
+
if (!this.dependencyResolver.isAllSatisfied(effectiveCall)) {
|
|
15163
|
+
const unsatisfied = effectiveCall.dependencies.filter(
|
|
14407
15164
|
(dep) => !this.dependencyResolver.isCompleted(dep)
|
|
14408
15165
|
);
|
|
14409
15166
|
this.logger.debug("Queueing gadget for later - waiting on dependencies", {
|
|
14410
|
-
gadgetName:
|
|
14411
|
-
invocationId:
|
|
15167
|
+
gadgetName: effectiveCall.gadgetName,
|
|
15168
|
+
invocationId: effectiveCall.invocationId,
|
|
14412
15169
|
waitingOn: unsatisfied
|
|
14413
15170
|
});
|
|
14414
|
-
this.dependencyResolver.addPending(
|
|
15171
|
+
this.dependencyResolver.addPending(effectiveCall);
|
|
14415
15172
|
return;
|
|
14416
15173
|
}
|
|
14417
|
-
for await (const evt of this._checkLimitThenExecute(
|
|
15174
|
+
for await (const evt of this._checkLimitThenExecute(effectiveCall)) {
|
|
14418
15175
|
yield evt;
|
|
14419
15176
|
}
|
|
14420
15177
|
for await (const evt of this.processPendingGadgets()) {
|
|
@@ -14553,7 +15310,31 @@ var init_gadget_dispatcher = __esm({
|
|
|
14553
15310
|
queuedCount: this.concurrencyManager.getQueuedGadgetCount()
|
|
14554
15311
|
});
|
|
14555
15312
|
const POLL_INTERVAL_MS = 100;
|
|
15313
|
+
const startTime = Date.now();
|
|
14556
15314
|
while (this.concurrencyManager.inFlightCount > 0 || this.concurrencyManager.hasQueuedGadgets()) {
|
|
15315
|
+
if (Date.now() - startTime >= this.inFlightTimeoutMs) {
|
|
15316
|
+
const timedOutEntries = this.concurrencyManager.getInFlightEntries();
|
|
15317
|
+
this.logger.error("In-flight gadget timeout exceeded, force-clearing remaining gadgets", {
|
|
15318
|
+
timeoutMs: this.inFlightTimeoutMs,
|
|
15319
|
+
remainingInFlight: timedOutEntries.length,
|
|
15320
|
+
remainingQueued: this.concurrencyManager.getQueuedGadgetCount(),
|
|
15321
|
+
timedOutInvocations: timedOutEntries.map((e) => e.invocationId)
|
|
15322
|
+
});
|
|
15323
|
+
const timeoutError = `Gadget execution timed out after ${this.inFlightTimeoutMs}ms`;
|
|
15324
|
+
for (const { invocationId, gadgetName } of timedOutEntries) {
|
|
15325
|
+
this.dependencyResolver.markFailed(invocationId);
|
|
15326
|
+
yield {
|
|
15327
|
+
type: "gadget_skipped",
|
|
15328
|
+
gadgetName,
|
|
15329
|
+
invocationId,
|
|
15330
|
+
parameters: {},
|
|
15331
|
+
failedDependency: invocationId,
|
|
15332
|
+
failedDependencyError: timeoutError
|
|
15333
|
+
};
|
|
15334
|
+
}
|
|
15335
|
+
this.concurrencyManager.clearInFlight();
|
|
15336
|
+
break;
|
|
15337
|
+
}
|
|
14557
15338
|
const allDone = this.concurrencyManager.getAllDonePromise();
|
|
14558
15339
|
const result = await Promise.race([
|
|
14559
15340
|
allDone,
|
|
@@ -15044,7 +15825,7 @@ var init_stream_processor = __esm({
|
|
|
15044
15825
|
"src/agent/stream-processor.ts"() {
|
|
15045
15826
|
"use strict";
|
|
15046
15827
|
init_executor();
|
|
15047
|
-
|
|
15828
|
+
init_parser2();
|
|
15048
15829
|
init_logger();
|
|
15049
15830
|
init_gadget_concurrency_manager();
|
|
15050
15831
|
init_gadget_dependency_resolver();
|
|
@@ -15139,7 +15920,8 @@ var init_stream_processor = __esm({
|
|
|
15139
15920
|
const evts = [...this.completedResultsQueue];
|
|
15140
15921
|
this.completedResultsQueue = [];
|
|
15141
15922
|
return evts;
|
|
15142
|
-
}
|
|
15923
|
+
},
|
|
15924
|
+
inFlightTimeoutMs: options.inFlightTimeoutMs
|
|
15143
15925
|
});
|
|
15144
15926
|
}
|
|
15145
15927
|
/**
|
|
@@ -15363,6 +16145,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15363
16145
|
logger;
|
|
15364
16146
|
requestHumanInput;
|
|
15365
16147
|
defaultGadgetTimeoutMs;
|
|
16148
|
+
inFlightTimeoutMs;
|
|
15366
16149
|
gadgetExecutionMode;
|
|
15367
16150
|
client;
|
|
15368
16151
|
mediaStore;
|
|
@@ -15381,6 +16164,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15381
16164
|
this.logger = options.logger;
|
|
15382
16165
|
this.requestHumanInput = options.requestHumanInput;
|
|
15383
16166
|
this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;
|
|
16167
|
+
this.inFlightTimeoutMs = options.inFlightTimeoutMs;
|
|
15384
16168
|
this.gadgetExecutionMode = options.gadgetExecutionMode;
|
|
15385
16169
|
this.client = options.client;
|
|
15386
16170
|
this.mediaStore = options.mediaStore;
|
|
@@ -15412,6 +16196,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15412
16196
|
logger: this.logger.getSubLogger({ name: "stream-processor" }),
|
|
15413
16197
|
requestHumanInput: this.requestHumanInput,
|
|
15414
16198
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
16199
|
+
inFlightTimeoutMs: this.inFlightTimeoutMs,
|
|
15415
16200
|
gadgetExecutionMode: this.gadgetExecutionMode,
|
|
15416
16201
|
client: this.client,
|
|
15417
16202
|
mediaStore: this.mediaStore,
|
|
@@ -16206,11 +16991,14 @@ __export(index_exports, {
|
|
|
16206
16991
|
OpenRouterProvider: () => OpenRouterProvider,
|
|
16207
16992
|
RateLimitTracker: () => RateLimitTracker,
|
|
16208
16993
|
SimpleSessionManager: () => SimpleSessionManager,
|
|
16994
|
+
Skill: () => Skill,
|
|
16995
|
+
SkillRegistry: () => SkillRegistry,
|
|
16209
16996
|
SlidingWindowStrategy: () => SlidingWindowStrategy,
|
|
16210
16997
|
StreamProcessor: () => StreamProcessor,
|
|
16211
16998
|
SummarizationStrategy: () => SummarizationStrategy,
|
|
16212
16999
|
TaskCompletionSignal: () => TaskCompletionSignal,
|
|
16213
17000
|
TimeoutException: () => TimeoutException,
|
|
17001
|
+
USE_SKILL_GADGET_NAME: () => USE_SKILL_GADGET_NAME,
|
|
16214
17002
|
audioFromBase64: () => audioFromBase64,
|
|
16215
17003
|
audioFromBuffer: () => audioFromBuffer,
|
|
16216
17004
|
collectEvents: () => collectEvents,
|
|
@@ -16228,10 +17016,12 @@ __export(index_exports, {
|
|
|
16228
17016
|
createOpenAIProviderFromEnv: () => createOpenAIProviderFromEnv,
|
|
16229
17017
|
createOpenRouterProviderFromEnv: () => createOpenRouterProviderFromEnv,
|
|
16230
17018
|
createSubagent: () => createSubagent,
|
|
17019
|
+
createUseSkillGadget: () => createUseSkillGadget,
|
|
16231
17020
|
defaultLogger: () => defaultLogger,
|
|
16232
17021
|
detectAudioMimeType: () => detectAudioMimeType,
|
|
16233
17022
|
detectImageMimeType: () => detectImageMimeType,
|
|
16234
17023
|
discoverProviderAdapters: () => discoverProviderAdapters,
|
|
17024
|
+
discoverSkills: () => discoverSkills,
|
|
16235
17025
|
extractMessageText: () => extractMessageText,
|
|
16236
17026
|
extractRetryAfterMs: () => extractRetryAfterMs,
|
|
16237
17027
|
filterByDepth: () => filterByDepth,
|
|
@@ -16274,15 +17064,21 @@ __export(index_exports, {
|
|
|
16274
17064
|
iterationProgressHint: () => iterationProgressHint,
|
|
16275
17065
|
listPresets: () => listPresets,
|
|
16276
17066
|
listSubagents: () => listSubagents,
|
|
17067
|
+
loadSkillsFromDirectory: () => loadSkillsFromDirectory,
|
|
16277
17068
|
normalizeMessageContent: () => normalizeMessageContent,
|
|
16278
17069
|
parallelGadgetHint: () => parallelGadgetHint,
|
|
16279
17070
|
parseDataUrl: () => parseDataUrl,
|
|
17071
|
+
parseFrontmatter: () => parseFrontmatter,
|
|
16280
17072
|
parseManifest: () => parseManifest,
|
|
17073
|
+
parseMetadata: () => parseMetadata,
|
|
16281
17074
|
parseRetryAfterHeader: () => parseRetryAfterHeader,
|
|
17075
|
+
parseSkillContent: () => parseSkillContent,
|
|
17076
|
+
parseSkillFile: () => parseSkillFile,
|
|
16282
17077
|
randomDelay: () => randomDelay,
|
|
16283
17078
|
resetFileLoggingState: () => resetFileLoggingState,
|
|
16284
17079
|
resolveConfig: () => resolveConfig,
|
|
16285
17080
|
resolveHintTemplate: () => resolveHintTemplate,
|
|
17081
|
+
resolveInstructions: () => resolveInstructions,
|
|
16286
17082
|
resolveModel: () => resolveModel,
|
|
16287
17083
|
resolvePromptTemplate: () => resolvePromptTemplate,
|
|
16288
17084
|
resolveRateLimitConfig: () => resolveRateLimitConfig,
|
|
@@ -16297,9 +17093,12 @@ __export(index_exports, {
|
|
|
16297
17093
|
resultWithImages: () => resultWithImages,
|
|
16298
17094
|
resultWithMedia: () => resultWithMedia,
|
|
16299
17095
|
runWithHandlers: () => runWithHandlers,
|
|
17096
|
+
scanResources: () => scanResources,
|
|
16300
17097
|
schemaToJSONSchema: () => schemaToJSONSchema,
|
|
16301
17098
|
stream: () => stream,
|
|
16302
17099
|
stripProviderPrefix: () => stripProviderPrefix,
|
|
17100
|
+
substituteArguments: () => substituteArguments,
|
|
17101
|
+
substituteVariables: () => substituteVariables,
|
|
16303
17102
|
text: () => text,
|
|
16304
17103
|
timing: () => timing,
|
|
16305
17104
|
toBase64: () => toBase64,
|
|
@@ -16307,13 +17106,14 @@ __export(index_exports, {
|
|
|
16307
17106
|
validateAndApplyDefaults: () => validateAndApplyDefaults,
|
|
16308
17107
|
validateGadgetParams: () => validateGadgetParams,
|
|
16309
17108
|
validateGadgetSchema: () => validateGadgetSchema,
|
|
17109
|
+
validateMetadata: () => validateMetadata,
|
|
16310
17110
|
withErrorHandling: () => withErrorHandling,
|
|
16311
17111
|
withRetry: () => withRetry,
|
|
16312
17112
|
withTimeout: () => withTimeout,
|
|
16313
|
-
z: () =>
|
|
17113
|
+
z: () => import_zod4.z
|
|
16314
17114
|
});
|
|
16315
17115
|
module.exports = __toCommonJS(index_exports);
|
|
16316
|
-
var
|
|
17116
|
+
var import_zod4 = require("zod");
|
|
16317
17117
|
init_agent();
|
|
16318
17118
|
init_builder();
|
|
16319
17119
|
init_event_handlers();
|
|
@@ -16627,7 +17427,7 @@ function resultWithFile(result, fileData, mimeType, options) {
|
|
|
16627
17427
|
|
|
16628
17428
|
// src/index.ts
|
|
16629
17429
|
init_output_viewer();
|
|
16630
|
-
|
|
17430
|
+
init_parser2();
|
|
16631
17431
|
init_registry();
|
|
16632
17432
|
init_typed_gadget();
|
|
16633
17433
|
init_constants2();
|
|
@@ -16894,6 +17694,14 @@ var SimpleSessionManager = class extends BaseSessionManager {
|
|
|
16894
17694
|
}
|
|
16895
17695
|
};
|
|
16896
17696
|
|
|
17697
|
+
// src/skills/index.ts
|
|
17698
|
+
init_activation();
|
|
17699
|
+
init_loader();
|
|
17700
|
+
init_parser();
|
|
17701
|
+
init_registry2();
|
|
17702
|
+
init_skill();
|
|
17703
|
+
init_use_skill_gadget();
|
|
17704
|
+
|
|
16897
17705
|
// src/utils/format.ts
|
|
16898
17706
|
function truncate(text3, maxLength, suffix = "...") {
|
|
16899
17707
|
if (text3.length <= maxLength) return text3;
|
|
@@ -17090,11 +17898,14 @@ function getHostExports2(ctx) {
|
|
|
17090
17898
|
OpenRouterProvider,
|
|
17091
17899
|
RateLimitTracker,
|
|
17092
17900
|
SimpleSessionManager,
|
|
17901
|
+
Skill,
|
|
17902
|
+
SkillRegistry,
|
|
17093
17903
|
SlidingWindowStrategy,
|
|
17094
17904
|
StreamProcessor,
|
|
17095
17905
|
SummarizationStrategy,
|
|
17096
17906
|
TaskCompletionSignal,
|
|
17097
17907
|
TimeoutException,
|
|
17908
|
+
USE_SKILL_GADGET_NAME,
|
|
17098
17909
|
audioFromBase64,
|
|
17099
17910
|
audioFromBuffer,
|
|
17100
17911
|
collectEvents,
|
|
@@ -17112,10 +17923,12 @@ function getHostExports2(ctx) {
|
|
|
17112
17923
|
createOpenAIProviderFromEnv,
|
|
17113
17924
|
createOpenRouterProviderFromEnv,
|
|
17114
17925
|
createSubagent,
|
|
17926
|
+
createUseSkillGadget,
|
|
17115
17927
|
defaultLogger,
|
|
17116
17928
|
detectAudioMimeType,
|
|
17117
17929
|
detectImageMimeType,
|
|
17118
17930
|
discoverProviderAdapters,
|
|
17931
|
+
discoverSkills,
|
|
17119
17932
|
extractMessageText,
|
|
17120
17933
|
extractRetryAfterMs,
|
|
17121
17934
|
filterByDepth,
|
|
@@ -17158,15 +17971,21 @@ function getHostExports2(ctx) {
|
|
|
17158
17971
|
iterationProgressHint,
|
|
17159
17972
|
listPresets,
|
|
17160
17973
|
listSubagents,
|
|
17974
|
+
loadSkillsFromDirectory,
|
|
17161
17975
|
normalizeMessageContent,
|
|
17162
17976
|
parallelGadgetHint,
|
|
17163
17977
|
parseDataUrl,
|
|
17978
|
+
parseFrontmatter,
|
|
17164
17979
|
parseManifest,
|
|
17980
|
+
parseMetadata,
|
|
17165
17981
|
parseRetryAfterHeader,
|
|
17982
|
+
parseSkillContent,
|
|
17983
|
+
parseSkillFile,
|
|
17166
17984
|
randomDelay,
|
|
17167
17985
|
resetFileLoggingState,
|
|
17168
17986
|
resolveConfig,
|
|
17169
17987
|
resolveHintTemplate,
|
|
17988
|
+
resolveInstructions,
|
|
17170
17989
|
resolveModel,
|
|
17171
17990
|
resolvePromptTemplate,
|
|
17172
17991
|
resolveRateLimitConfig,
|
|
@@ -17181,9 +18000,12 @@ function getHostExports2(ctx) {
|
|
|
17181
18000
|
resultWithImages,
|
|
17182
18001
|
resultWithMedia,
|
|
17183
18002
|
runWithHandlers,
|
|
18003
|
+
scanResources,
|
|
17184
18004
|
schemaToJSONSchema,
|
|
17185
18005
|
stream,
|
|
17186
18006
|
stripProviderPrefix,
|
|
18007
|
+
substituteArguments,
|
|
18008
|
+
substituteVariables,
|
|
17187
18009
|
text,
|
|
17188
18010
|
timing,
|
|
17189
18011
|
toBase64,
|
|
@@ -17191,6 +18013,7 @@ function getHostExports2(ctx) {
|
|
|
17191
18013
|
validateAndApplyDefaults,
|
|
17192
18014
|
validateGadgetParams,
|
|
17193
18015
|
validateGadgetSchema,
|
|
18016
|
+
validateMetadata,
|
|
17194
18017
|
withErrorHandling,
|
|
17195
18018
|
withRetry,
|
|
17196
18019
|
withTimeout,
|