@theokit/sdk 2.24.0 → 2.26.0
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/CHANGELOG.md +57 -0
- package/dist/a2a/index.cjs +464 -195
- package/dist/a2a/index.cjs.map +1 -1
- package/dist/a2a/index.js +464 -195
- package/dist/a2a/index.js.map +1 -1
- package/dist/create-skill.d.ts +8 -0
- package/dist/{cron-vjod0qVQ.d.ts → cron-BR1NCSk1.d.cts} +77 -4
- package/dist/{cron-Bd2oRD7A.d.cts → cron-DgEQCJ2i.d.ts} +77 -4
- package/dist/cron.cjs +430 -184
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.d.cts +2 -2
- package/dist/cron.d.ts +2 -2
- package/dist/cron.js +430 -184
- package/dist/cron.js.map +1 -1
- package/dist/{errors-DRS-kqOK.d.ts → errors-CbY3pxY7.d.ts} +1 -1
- package/dist/{errors-DIKBXffg.d.cts → errors-DLMNb4Ka.d.cts} +1 -1
- package/dist/errors.d.cts +2 -2
- package/dist/eval.cjs +430 -184
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +430 -184
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +523 -190
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -7
- package/dist/index.d.ts +93 -7
- package/dist/index.js +520 -191
- package/dist/index.js.map +1 -1
- package/dist/internal/runtime/local-agent/local-agent-bootstrap.d.ts +2 -4
- package/dist/internal/runtime/processors/run-processors.d.ts +10 -0
- package/dist/internal/runtime/processors/tripwire-run.d.ts +16 -0
- package/dist/internal/runtime/processors/wrap-output-run.d.ts +18 -0
- package/dist/internal/runtime/skills/skill-frontmatter.d.ts +6 -0
- package/dist/{run-Cr0C6cOM.d.cts → run-CdWiihyU.d.cts} +109 -2
- package/dist/{run-Cr0C6cOM.d.ts → run-CdWiihyU.d.ts} +109 -2
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.js.map +1 -1
- package/dist/types/agent.d.ts +67 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/processors.d.ts +84 -0
- package/dist/types/run-events.d.ts +11 -1
- package/dist/types/run.d.ts +12 -0
- package/package.json +1 -1
package/dist/eval.cjs
CHANGED
|
@@ -3457,7 +3457,8 @@ function stripSecretsFromOptions(options) {
|
|
|
3457
3457
|
local: serializeLocal(options.local),
|
|
3458
3458
|
cloud: serializeCloud(options.cloud),
|
|
3459
3459
|
memory: serializeMemory(options.memory),
|
|
3460
|
-
|
|
3460
|
+
// SE22 — a SkillsResolver function isn't serializable; persist only the static form.
|
|
3461
|
+
skills: serializeEnabledList(typeof options.skills === "function" ? void 0 : options.skills),
|
|
3461
3462
|
// Code-`Plugin` objects are closures and cannot be persisted (like custom
|
|
3462
3463
|
// tools); only the named-enable settings form is serialized.
|
|
3463
3464
|
plugins: serializeEnabledList(asPluginsSettings(options.plugins)),
|
|
@@ -3765,6 +3766,7 @@ function serializeCloud2(cloud) {
|
|
|
3765
3766
|
return result;
|
|
3766
3767
|
}
|
|
3767
3768
|
function serializeSkills(skills) {
|
|
3769
|
+
if (typeof skills === "function") return void 0;
|
|
3768
3770
|
if (skills?.enabled === void 0 || skills.enabled.length === 0) return void 0;
|
|
3769
3771
|
return { enabled: [...skills.enabled] };
|
|
3770
3772
|
}
|
|
@@ -5236,8 +5238,19 @@ init_errors();
|
|
|
5236
5238
|
function validateCloudToolParity(options) {
|
|
5237
5239
|
if (options.cloud === void 0) return;
|
|
5238
5240
|
rejectFunctionSystemPrompt(options);
|
|
5241
|
+
rejectFunctionSkills(options);
|
|
5242
|
+
rejectProcessors(options);
|
|
5239
5243
|
rejectStdioMcpLocalPaths(options);
|
|
5240
5244
|
}
|
|
5245
|
+
function rejectProcessors(options) {
|
|
5246
|
+
const hasProcessors = (options.inputProcessors?.length ?? 0) > 0 || (options.outputProcessors?.length ?? 0) > 0;
|
|
5247
|
+
if (hasProcessors) {
|
|
5248
|
+
throw new ConfigurationError(
|
|
5249
|
+
"Cloud agents can't run guardrail processors \u2014 a Processor carries function handlers that don't survive serialization to PaaS. Run processors on a local agent, or move the guardrail into a server-side gateway in front of TheoCloud.",
|
|
5250
|
+
{ code: "cloud_incompatible_function_resolver" }
|
|
5251
|
+
);
|
|
5252
|
+
}
|
|
5253
|
+
}
|
|
5241
5254
|
function rejectFunctionSystemPrompt(options) {
|
|
5242
5255
|
if (typeof options.systemPrompt === "function") {
|
|
5243
5256
|
throw new ConfigurationError(
|
|
@@ -5246,6 +5259,14 @@ function rejectFunctionSystemPrompt(options) {
|
|
|
5246
5259
|
);
|
|
5247
5260
|
}
|
|
5248
5261
|
}
|
|
5262
|
+
function rejectFunctionSkills(options) {
|
|
5263
|
+
if (typeof options.skills === "function") {
|
|
5264
|
+
throw new ConfigurationError(
|
|
5265
|
+
"Cloud agents require skills as a static settings object. SkillsResolver functions can't run on PaaS \u2014 resolve to a SkillsSettings object before Agent.create() or move the dynamic logic into a hook rule.",
|
|
5266
|
+
{ code: "cloud_incompatible_function_resolver" }
|
|
5267
|
+
);
|
|
5268
|
+
}
|
|
5269
|
+
}
|
|
5249
5270
|
function rejectStdioMcpLocalPaths(options) {
|
|
5250
5271
|
if (options.mcpServers === void 0) return;
|
|
5251
5272
|
for (const [name, config] of Object.entries(options.mcpServers)) {
|
|
@@ -7102,9 +7123,223 @@ function parseFrontmatterFields(frontmatter) {
|
|
|
7102
7123
|
return out;
|
|
7103
7124
|
}
|
|
7104
7125
|
|
|
7126
|
+
// src/internal/runtime/skills/discover-skills.ts
|
|
7127
|
+
init_errors();
|
|
7128
|
+
|
|
7129
|
+
// src/internal/runtime/skills/skill-frontmatter.ts
|
|
7130
|
+
init_errors();
|
|
7131
|
+
init_yaml_frontmatter();
|
|
7132
|
+
function asString(v) {
|
|
7133
|
+
return typeof v === "string" ? v : void 0;
|
|
7134
|
+
}
|
|
7135
|
+
function toStringFields(raw) {
|
|
7136
|
+
const out = {};
|
|
7137
|
+
for (const [k, v] of Object.entries(raw)) out[k] = asString(v);
|
|
7138
|
+
return out;
|
|
7139
|
+
}
|
|
7140
|
+
function parseSkillFrontmatter(raw, fallbackName) {
|
|
7141
|
+
const fields = extractAndParseFrontmatter(raw, fallbackName);
|
|
7142
|
+
const name = resolveName(fields, fallbackName);
|
|
7143
|
+
ensureRequiredFields(fields, name);
|
|
7144
|
+
return buildFrontmatter(fields, name);
|
|
7145
|
+
}
|
|
7146
|
+
function stripSkillFrontmatter(raw) {
|
|
7147
|
+
const match = /^---\s*\n[\s\S]*?\n---\s*\n/.exec(raw);
|
|
7148
|
+
return (match === null ? raw : raw.slice(match[0].length)).trim();
|
|
7149
|
+
}
|
|
7150
|
+
function extractAndParseFrontmatter(raw, fallbackName) {
|
|
7151
|
+
const match = /^---\s*\n([\s\S]*?)\n---\s*\n/.exec(raw);
|
|
7152
|
+
if (match === null) {
|
|
7153
|
+
throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {
|
|
7154
|
+
code: "missing_frontmatter"
|
|
7155
|
+
});
|
|
7156
|
+
}
|
|
7157
|
+
const frontmatter = match[1] ?? "";
|
|
7158
|
+
try {
|
|
7159
|
+
return toStringFields(parseSimpleYaml(frontmatter));
|
|
7160
|
+
} catch (cause) {
|
|
7161
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
7162
|
+
throw new ConfigurationError(
|
|
7163
|
+
`Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,
|
|
7164
|
+
{ code: "schema_invalid", cause }
|
|
7165
|
+
);
|
|
7166
|
+
}
|
|
7167
|
+
}
|
|
7168
|
+
function resolveName(fields, fallbackName) {
|
|
7169
|
+
if (hasContent(fields.name)) return fields.name;
|
|
7170
|
+
if (hasContent(fallbackName)) return fallbackName;
|
|
7171
|
+
throw new ConfigurationError("Skill at unknown path is missing required field: name", {
|
|
7172
|
+
code: "schema_invalid"
|
|
7173
|
+
});
|
|
7174
|
+
}
|
|
7175
|
+
function ensureRequiredFields(fields, name) {
|
|
7176
|
+
if (!hasContent(fields.description)) {
|
|
7177
|
+
throw new ConfigurationError(`Skill ${name} is missing required field: description`, {
|
|
7178
|
+
code: "schema_invalid"
|
|
7179
|
+
});
|
|
7180
|
+
}
|
|
7181
|
+
}
|
|
7182
|
+
function buildFrontmatter(fields, name) {
|
|
7183
|
+
const description = fields.description;
|
|
7184
|
+
if (description === void 0) {
|
|
7185
|
+
throw new ConfigurationError(`Skill ${name} missing description`, { code: "schema_invalid" });
|
|
7186
|
+
}
|
|
7187
|
+
const result = { name, description };
|
|
7188
|
+
if (hasContent(fields.category)) result.category = fields.category;
|
|
7189
|
+
const deps = parseDependencies(fields.dependencies);
|
|
7190
|
+
if (deps !== void 0) result.dependencies = deps;
|
|
7191
|
+
return result;
|
|
7192
|
+
}
|
|
7193
|
+
function parseDependencies(raw) {
|
|
7194
|
+
if (!hasContent(raw)) return void 0;
|
|
7195
|
+
const deps = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
7196
|
+
return deps.length > 0 ? deps : void 0;
|
|
7197
|
+
}
|
|
7198
|
+
function hasContent(value) {
|
|
7199
|
+
return value !== void 0 && value.trim().length > 0;
|
|
7200
|
+
}
|
|
7201
|
+
|
|
7202
|
+
// src/internal/runtime/skills/discover-skills.ts
|
|
7203
|
+
async function discoverSkills(dir, options) {
|
|
7204
|
+
let entries;
|
|
7205
|
+
try {
|
|
7206
|
+
entries = await readWorkspaceDir(dir, "skills_read_error", "skills directory");
|
|
7207
|
+
} catch {
|
|
7208
|
+
return [];
|
|
7209
|
+
}
|
|
7210
|
+
const skills = [];
|
|
7211
|
+
for (const entry of entries) {
|
|
7212
|
+
if (!entry.isDirectory()) continue;
|
|
7213
|
+
let skillDir;
|
|
7214
|
+
try {
|
|
7215
|
+
skillDir = safePathJoin(dir, entry.name);
|
|
7216
|
+
assertNoSymlinkEscape(skillDir, dir);
|
|
7217
|
+
} catch {
|
|
7218
|
+
continue;
|
|
7219
|
+
}
|
|
7220
|
+
const skillPath = path.join(skillDir, "SKILL.md");
|
|
7221
|
+
let raw;
|
|
7222
|
+
try {
|
|
7223
|
+
raw = await promises.readFile(skillPath, "utf8");
|
|
7224
|
+
} catch {
|
|
7225
|
+
continue;
|
|
7226
|
+
}
|
|
7227
|
+
const skill = tryParseSkill(raw, entry.name, skillPath, options);
|
|
7228
|
+
if (skill !== void 0) skills.push(skill);
|
|
7229
|
+
}
|
|
7230
|
+
return skills;
|
|
7231
|
+
}
|
|
7232
|
+
function tryParseSkill(raw, fallbackName, source, options) {
|
|
7233
|
+
try {
|
|
7234
|
+
const frontmatter = parseSkillFrontmatter(raw, fallbackName);
|
|
7235
|
+
const skill = {
|
|
7236
|
+
name: frontmatter.name,
|
|
7237
|
+
description: frontmatter.description,
|
|
7238
|
+
source
|
|
7239
|
+
};
|
|
7240
|
+
if (frontmatter.category !== void 0) skill.category = frontmatter.category;
|
|
7241
|
+
if (frontmatter.dependencies !== void 0) skill.dependencies = frontmatter.dependencies;
|
|
7242
|
+
return skill;
|
|
7243
|
+
} catch (cause) {
|
|
7244
|
+
if (cause instanceof ConfigurationError) {
|
|
7245
|
+
options?.onInvalidSkill?.({
|
|
7246
|
+
name: fallbackName,
|
|
7247
|
+
source,
|
|
7248
|
+
code: cause.code ?? "unknown",
|
|
7249
|
+
message: cause.message
|
|
7250
|
+
});
|
|
7251
|
+
return void 0;
|
|
7252
|
+
}
|
|
7253
|
+
throw cause;
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
|
|
7257
|
+
// src/internal/runtime/skills/skills-manager.ts
|
|
7258
|
+
var SkillsManager = class {
|
|
7259
|
+
constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
|
|
7260
|
+
this.cwd = cwd;
|
|
7261
|
+
this.settingSourcesIncludeProject = settingSourcesIncludeProject;
|
|
7262
|
+
this.skillsDir = skillsDir;
|
|
7263
|
+
this.inline = inline;
|
|
7264
|
+
}
|
|
7265
|
+
cwd;
|
|
7266
|
+
settingSourcesIncludeProject;
|
|
7267
|
+
skillsDir;
|
|
7268
|
+
inline;
|
|
7269
|
+
skills = [];
|
|
7270
|
+
async initialize() {
|
|
7271
|
+
if (!this.settingSourcesIncludeProject) {
|
|
7272
|
+
this.skills = this.mergeInline([]);
|
|
7273
|
+
return;
|
|
7274
|
+
}
|
|
7275
|
+
await this.refresh();
|
|
7276
|
+
}
|
|
7277
|
+
async refresh() {
|
|
7278
|
+
const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
|
|
7279
|
+
const discovered = await discoverSkills(skillsRoot, {
|
|
7280
|
+
onInvalidSkill: (info) => {
|
|
7281
|
+
process.stderr.write(
|
|
7282
|
+
`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
|
|
7283
|
+
`
|
|
7284
|
+
);
|
|
7285
|
+
}
|
|
7286
|
+
});
|
|
7287
|
+
this.skills = this.mergeInline(discovered);
|
|
7288
|
+
}
|
|
7289
|
+
/** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
|
|
7290
|
+
mergeInline(discovered) {
|
|
7291
|
+
if (this.inline === void 0 || this.inline.length === 0) return discovered;
|
|
7292
|
+
const inlineNames = new Set(this.inline.map((s) => s.name));
|
|
7293
|
+
return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
|
|
7294
|
+
}
|
|
7295
|
+
list() {
|
|
7296
|
+
return Promise.resolve(this.skills);
|
|
7297
|
+
}
|
|
7298
|
+
/**
|
|
7299
|
+
* SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
|
|
7300
|
+
* skills carry `instructions` on the object; filesystem skills read the body
|
|
7301
|
+
* from their `source` SKILL.md (frontmatter stripped). `undefined` when no
|
|
7302
|
+
* enabled skill matches (malformed skills were already excluded at discovery).
|
|
7303
|
+
*/
|
|
7304
|
+
async get(name) {
|
|
7305
|
+
const skill = this.skills.find((s) => s.name === name);
|
|
7306
|
+
if (skill === void 0) return void 0;
|
|
7307
|
+
const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await promises.readFile(skill.source, "utf8"));
|
|
7308
|
+
const references = skill.references;
|
|
7309
|
+
return {
|
|
7310
|
+
name: skill.name,
|
|
7311
|
+
description: skill.description,
|
|
7312
|
+
instructions,
|
|
7313
|
+
...references !== void 0 ? { references } : {}
|
|
7314
|
+
};
|
|
7315
|
+
}
|
|
7316
|
+
};
|
|
7317
|
+
|
|
7105
7318
|
// src/internal/runtime/system-prompt/local-assembly.ts
|
|
7106
|
-
async function
|
|
7107
|
-
const skills = inputs.
|
|
7319
|
+
async function resolveSendSkills(inputs, userText, memoryFacts) {
|
|
7320
|
+
const skills = inputs.options.skills;
|
|
7321
|
+
if (typeof skills !== "function") {
|
|
7322
|
+
return { manager: inputs.skillsManager, autoInject: skills?.autoInject ?? true };
|
|
7323
|
+
}
|
|
7324
|
+
const settings = await skills({
|
|
7325
|
+
agentId: inputs.agentId,
|
|
7326
|
+
cwd: inputs.workspaceCwd,
|
|
7327
|
+
model: inputs.model,
|
|
7328
|
+
userMessage: userText,
|
|
7329
|
+
memory: memoryFacts.map((fact) => ({ text: fact.text }))
|
|
7330
|
+
});
|
|
7331
|
+
const manager = new SkillsManager(
|
|
7332
|
+
inputs.workspaceCwd,
|
|
7333
|
+
settings.enabled,
|
|
7334
|
+
inputs.settingSourcesIncludeProject,
|
|
7335
|
+
settings.skillsDir,
|
|
7336
|
+
settings.inline
|
|
7337
|
+
);
|
|
7338
|
+
await manager.initialize();
|
|
7339
|
+
return { manager, autoInject: settings.autoInject ?? true };
|
|
7340
|
+
}
|
|
7341
|
+
async function buildSystemPromptContext(inputs, userText, memoryFacts, manager = inputs.skillsManager) {
|
|
7342
|
+
const skills = manager !== void 0 ? await manager.list() : [];
|
|
7108
7343
|
return {
|
|
7109
7344
|
agentId: inputs.agentId,
|
|
7110
7345
|
cwd: inputs.workspaceCwd,
|
|
@@ -7115,10 +7350,11 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts) {
|
|
|
7115
7350
|
};
|
|
7116
7351
|
}
|
|
7117
7352
|
async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary) {
|
|
7118
|
-
const
|
|
7353
|
+
const resolved = await resolveSendSkills(inputs, userText, memoryFacts);
|
|
7354
|
+
const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts, resolved.manager);
|
|
7119
7355
|
const assemblyCtx = {
|
|
7120
7356
|
...baseCtx,
|
|
7121
|
-
skillsAutoInject:
|
|
7357
|
+
skillsAutoInject: resolved.autoInject,
|
|
7122
7358
|
memoryAutoInject: inputs.options.memory?.autoInject ?? true
|
|
7123
7359
|
};
|
|
7124
7360
|
if (baseSystemPrompt !== void 0) assemblyCtx.baseSystemPrompt = baseSystemPrompt;
|
|
@@ -8370,176 +8606,6 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
|
|
|
8370
8606
|
return metadata;
|
|
8371
8607
|
}
|
|
8372
8608
|
|
|
8373
|
-
// src/internal/runtime/skills/discover-skills.ts
|
|
8374
|
-
init_errors();
|
|
8375
|
-
|
|
8376
|
-
// src/internal/runtime/skills/skill-frontmatter.ts
|
|
8377
|
-
init_errors();
|
|
8378
|
-
init_yaml_frontmatter();
|
|
8379
|
-
function asString(v) {
|
|
8380
|
-
return typeof v === "string" ? v : void 0;
|
|
8381
|
-
}
|
|
8382
|
-
function toStringFields(raw) {
|
|
8383
|
-
const out = {};
|
|
8384
|
-
for (const [k, v] of Object.entries(raw)) out[k] = asString(v);
|
|
8385
|
-
return out;
|
|
8386
|
-
}
|
|
8387
|
-
function parseSkillFrontmatter(raw, fallbackName) {
|
|
8388
|
-
const fields = extractAndParseFrontmatter(raw, fallbackName);
|
|
8389
|
-
const name = resolveName(fields, fallbackName);
|
|
8390
|
-
ensureRequiredFields(fields, name);
|
|
8391
|
-
return buildFrontmatter(fields, name);
|
|
8392
|
-
}
|
|
8393
|
-
function extractAndParseFrontmatter(raw, fallbackName) {
|
|
8394
|
-
const match = /^---\s*\n([\s\S]*?)\n---\s*\n/.exec(raw);
|
|
8395
|
-
if (match === null) {
|
|
8396
|
-
throw new ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {
|
|
8397
|
-
code: "missing_frontmatter"
|
|
8398
|
-
});
|
|
8399
|
-
}
|
|
8400
|
-
const frontmatter = match[1] ?? "";
|
|
8401
|
-
try {
|
|
8402
|
-
return toStringFields(parseSimpleYaml(frontmatter));
|
|
8403
|
-
} catch (cause) {
|
|
8404
|
-
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
8405
|
-
throw new ConfigurationError(
|
|
8406
|
-
`Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,
|
|
8407
|
-
{ code: "schema_invalid", cause }
|
|
8408
|
-
);
|
|
8409
|
-
}
|
|
8410
|
-
}
|
|
8411
|
-
function resolveName(fields, fallbackName) {
|
|
8412
|
-
if (hasContent(fields.name)) return fields.name;
|
|
8413
|
-
if (hasContent(fallbackName)) return fallbackName;
|
|
8414
|
-
throw new ConfigurationError("Skill at unknown path is missing required field: name", {
|
|
8415
|
-
code: "schema_invalid"
|
|
8416
|
-
});
|
|
8417
|
-
}
|
|
8418
|
-
function ensureRequiredFields(fields, name) {
|
|
8419
|
-
if (!hasContent(fields.description)) {
|
|
8420
|
-
throw new ConfigurationError(`Skill ${name} is missing required field: description`, {
|
|
8421
|
-
code: "schema_invalid"
|
|
8422
|
-
});
|
|
8423
|
-
}
|
|
8424
|
-
}
|
|
8425
|
-
function buildFrontmatter(fields, name) {
|
|
8426
|
-
const description = fields.description;
|
|
8427
|
-
if (description === void 0) {
|
|
8428
|
-
throw new ConfigurationError(`Skill ${name} missing description`, { code: "schema_invalid" });
|
|
8429
|
-
}
|
|
8430
|
-
const result = { name, description };
|
|
8431
|
-
if (hasContent(fields.category)) result.category = fields.category;
|
|
8432
|
-
const deps = parseDependencies(fields.dependencies);
|
|
8433
|
-
if (deps !== void 0) result.dependencies = deps;
|
|
8434
|
-
return result;
|
|
8435
|
-
}
|
|
8436
|
-
function parseDependencies(raw) {
|
|
8437
|
-
if (!hasContent(raw)) return void 0;
|
|
8438
|
-
const deps = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
8439
|
-
return deps.length > 0 ? deps : void 0;
|
|
8440
|
-
}
|
|
8441
|
-
function hasContent(value) {
|
|
8442
|
-
return value !== void 0 && value.trim().length > 0;
|
|
8443
|
-
}
|
|
8444
|
-
|
|
8445
|
-
// src/internal/runtime/skills/discover-skills.ts
|
|
8446
|
-
async function discoverSkills(dir, options) {
|
|
8447
|
-
let entries;
|
|
8448
|
-
try {
|
|
8449
|
-
entries = await readWorkspaceDir(dir, "skills_read_error", "skills directory");
|
|
8450
|
-
} catch {
|
|
8451
|
-
return [];
|
|
8452
|
-
}
|
|
8453
|
-
const skills = [];
|
|
8454
|
-
for (const entry of entries) {
|
|
8455
|
-
if (!entry.isDirectory()) continue;
|
|
8456
|
-
let skillDir;
|
|
8457
|
-
try {
|
|
8458
|
-
skillDir = safePathJoin(dir, entry.name);
|
|
8459
|
-
assertNoSymlinkEscape(skillDir, dir);
|
|
8460
|
-
} catch {
|
|
8461
|
-
continue;
|
|
8462
|
-
}
|
|
8463
|
-
const skillPath = path.join(skillDir, "SKILL.md");
|
|
8464
|
-
let raw;
|
|
8465
|
-
try {
|
|
8466
|
-
raw = await promises.readFile(skillPath, "utf8");
|
|
8467
|
-
} catch {
|
|
8468
|
-
continue;
|
|
8469
|
-
}
|
|
8470
|
-
const skill = tryParseSkill(raw, entry.name, skillPath, options);
|
|
8471
|
-
if (skill !== void 0) skills.push(skill);
|
|
8472
|
-
}
|
|
8473
|
-
return skills;
|
|
8474
|
-
}
|
|
8475
|
-
function tryParseSkill(raw, fallbackName, source, options) {
|
|
8476
|
-
try {
|
|
8477
|
-
const frontmatter = parseSkillFrontmatter(raw, fallbackName);
|
|
8478
|
-
const skill = {
|
|
8479
|
-
name: frontmatter.name,
|
|
8480
|
-
description: frontmatter.description,
|
|
8481
|
-
source
|
|
8482
|
-
};
|
|
8483
|
-
if (frontmatter.category !== void 0) skill.category = frontmatter.category;
|
|
8484
|
-
if (frontmatter.dependencies !== void 0) skill.dependencies = frontmatter.dependencies;
|
|
8485
|
-
return skill;
|
|
8486
|
-
} catch (cause) {
|
|
8487
|
-
if (cause instanceof ConfigurationError) {
|
|
8488
|
-
options?.onInvalidSkill?.({
|
|
8489
|
-
name: fallbackName,
|
|
8490
|
-
source,
|
|
8491
|
-
code: cause.code ?? "unknown",
|
|
8492
|
-
message: cause.message
|
|
8493
|
-
});
|
|
8494
|
-
return void 0;
|
|
8495
|
-
}
|
|
8496
|
-
throw cause;
|
|
8497
|
-
}
|
|
8498
|
-
}
|
|
8499
|
-
|
|
8500
|
-
// src/internal/runtime/skills/skills-manager.ts
|
|
8501
|
-
var SkillsManager = class {
|
|
8502
|
-
constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
|
|
8503
|
-
this.cwd = cwd;
|
|
8504
|
-
this.settingSourcesIncludeProject = settingSourcesIncludeProject;
|
|
8505
|
-
this.skillsDir = skillsDir;
|
|
8506
|
-
this.inline = inline;
|
|
8507
|
-
}
|
|
8508
|
-
cwd;
|
|
8509
|
-
settingSourcesIncludeProject;
|
|
8510
|
-
skillsDir;
|
|
8511
|
-
inline;
|
|
8512
|
-
skills = [];
|
|
8513
|
-
async initialize() {
|
|
8514
|
-
if (!this.settingSourcesIncludeProject) {
|
|
8515
|
-
this.skills = this.mergeInline([]);
|
|
8516
|
-
return;
|
|
8517
|
-
}
|
|
8518
|
-
await this.refresh();
|
|
8519
|
-
}
|
|
8520
|
-
async refresh() {
|
|
8521
|
-
const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
|
|
8522
|
-
const discovered = await discoverSkills(skillsRoot, {
|
|
8523
|
-
onInvalidSkill: (info) => {
|
|
8524
|
-
process.stderr.write(
|
|
8525
|
-
`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
|
|
8526
|
-
`
|
|
8527
|
-
);
|
|
8528
|
-
}
|
|
8529
|
-
});
|
|
8530
|
-
this.skills = this.mergeInline(discovered);
|
|
8531
|
-
}
|
|
8532
|
-
/** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
|
|
8533
|
-
mergeInline(discovered) {
|
|
8534
|
-
if (this.inline === void 0 || this.inline.length === 0) return discovered;
|
|
8535
|
-
const inlineNames = new Set(this.inline.map((s) => s.name));
|
|
8536
|
-
return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
|
|
8537
|
-
}
|
|
8538
|
-
list() {
|
|
8539
|
-
return Promise.resolve(this.skills);
|
|
8540
|
-
}
|
|
8541
|
-
};
|
|
8542
|
-
|
|
8543
8609
|
// src/internal/runtime/local-agent/local-agent-bootstrap.ts
|
|
8544
8610
|
function registerLocalAgent(args) {
|
|
8545
8611
|
registerAgent({
|
|
@@ -8575,16 +8641,23 @@ function bootstrapSubmanagers(args) {
|
|
|
8575
8641
|
);
|
|
8576
8642
|
}
|
|
8577
8643
|
if (args.options.skills !== void 0 || args.settingSourcesIncludeProject) {
|
|
8644
|
+
const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
|
|
8578
8645
|
out.skillsManager = new SkillsManager(
|
|
8579
8646
|
args.workspaceCwd,
|
|
8580
|
-
|
|
8647
|
+
staticSkills?.enabled,
|
|
8581
8648
|
args.settingSourcesIncludeProject,
|
|
8582
8649
|
// M22 — custom skills directory + inline (code-defined) skills.
|
|
8583
|
-
|
|
8584
|
-
|
|
8650
|
+
staticSkills?.skillsDir,
|
|
8651
|
+
staticSkills?.inline
|
|
8585
8652
|
);
|
|
8586
8653
|
const localSkills = out.skillsManager;
|
|
8587
|
-
out.skills = {
|
|
8654
|
+
out.skills = {
|
|
8655
|
+
// Project to the public shape (name + description only). Inline skills carry
|
|
8656
|
+
// their body + references on the object; `list()` must never leak them —
|
|
8657
|
+
// the body is reachable exclusively through `get()`.
|
|
8658
|
+
list: async () => (await localSkills.list()).map((s) => ({ name: s.name, description: s.description })),
|
|
8659
|
+
get: (name) => localSkills.get(name)
|
|
8660
|
+
};
|
|
8588
8661
|
}
|
|
8589
8662
|
if (args.options.plugins !== void 0 || args.settingSourcesIncludePlugins) {
|
|
8590
8663
|
out.pluginsManager = new PluginsManager(
|
|
@@ -16076,6 +16149,145 @@ function ponyfillAny(signals) {
|
|
|
16076
16149
|
return ctrl.signal;
|
|
16077
16150
|
}
|
|
16078
16151
|
|
|
16152
|
+
// src/internal/runtime/processors/run-processors.ts
|
|
16153
|
+
var ProcessorAbort = class {
|
|
16154
|
+
constructor(processorId, reason) {
|
|
16155
|
+
this.processorId = processorId;
|
|
16156
|
+
this.reason = reason;
|
|
16157
|
+
}
|
|
16158
|
+
processorId;
|
|
16159
|
+
reason;
|
|
16160
|
+
};
|
|
16161
|
+
function fireViolation(processor, violation) {
|
|
16162
|
+
try {
|
|
16163
|
+
processor.onViolation?.(violation);
|
|
16164
|
+
} catch {
|
|
16165
|
+
}
|
|
16166
|
+
}
|
|
16167
|
+
function controlsFor(processor) {
|
|
16168
|
+
return {
|
|
16169
|
+
abort(reason) {
|
|
16170
|
+
throw new ProcessorAbort(processor.id, reason);
|
|
16171
|
+
},
|
|
16172
|
+
warn(message, detail) {
|
|
16173
|
+
fireViolation(processor, {
|
|
16174
|
+
processorId: processor.id,
|
|
16175
|
+
message,
|
|
16176
|
+
...detail !== void 0 ? { detail } : {}
|
|
16177
|
+
});
|
|
16178
|
+
}
|
|
16179
|
+
};
|
|
16180
|
+
}
|
|
16181
|
+
function selectHandler(processor, phase) {
|
|
16182
|
+
if (phase === "input") {
|
|
16183
|
+
return processor.processInput ? { kind: "input", fn: processor.processInput } : void 0;
|
|
16184
|
+
}
|
|
16185
|
+
return processor.processOutput ? { kind: "output", fn: processor.processOutput } : void 0;
|
|
16186
|
+
}
|
|
16187
|
+
function invokeHandler(handler, value, agentId, controls) {
|
|
16188
|
+
return handler.kind === "input" ? handler.fn({ message: value, agentId, ...controls }) : handler.fn({ text: value, agentId, ...controls });
|
|
16189
|
+
}
|
|
16190
|
+
async function runOneProcessor(processor, value, agentId, phase) {
|
|
16191
|
+
const handler = selectHandler(processor, phase);
|
|
16192
|
+
if (handler === void 0) return { value };
|
|
16193
|
+
try {
|
|
16194
|
+
const out = await invokeHandler(handler, value, agentId, controlsFor(processor));
|
|
16195
|
+
return { value: typeof out === "string" ? out : value };
|
|
16196
|
+
} catch (err) {
|
|
16197
|
+
if (!(err instanceof ProcessorAbort)) throw err;
|
|
16198
|
+
fireViolation(processor, { processorId: err.processorId, message: err.reason });
|
|
16199
|
+
return { tripwire: { reason: err.reason, processorId: err.processorId } };
|
|
16200
|
+
}
|
|
16201
|
+
}
|
|
16202
|
+
async function runPipeline(processors, initial, agentId, phase) {
|
|
16203
|
+
let value = initial;
|
|
16204
|
+
for (const processor of processors) {
|
|
16205
|
+
const step = await runOneProcessor(processor, value, agentId, phase);
|
|
16206
|
+
if ("tripwire" in step) return { kind: "tripwire", tripwire: step.tripwire };
|
|
16207
|
+
value = step.value;
|
|
16208
|
+
}
|
|
16209
|
+
return { kind: "ok", value };
|
|
16210
|
+
}
|
|
16211
|
+
function runInputProcessors(processors, message, agentId) {
|
|
16212
|
+
return runPipeline(processors, message, agentId, "input");
|
|
16213
|
+
}
|
|
16214
|
+
function runOutputProcessors(processors, text, agentId) {
|
|
16215
|
+
return runPipeline(processors, text, agentId, "output");
|
|
16216
|
+
}
|
|
16217
|
+
|
|
16218
|
+
// src/internal/runtime/processors/tripwire-run.ts
|
|
16219
|
+
var SUPPORTED = /* @__PURE__ */ new Set([
|
|
16220
|
+
"stream",
|
|
16221
|
+
"wait",
|
|
16222
|
+
"cancel",
|
|
16223
|
+
"conversation"
|
|
16224
|
+
]);
|
|
16225
|
+
function emptyStream() {
|
|
16226
|
+
return {
|
|
16227
|
+
next: () => Promise.resolve({ done: true, value: void 0 }),
|
|
16228
|
+
return: () => Promise.resolve({ done: true, value: void 0 }),
|
|
16229
|
+
throw: (err) => Promise.reject(err),
|
|
16230
|
+
[Symbol.asyncIterator]() {
|
|
16231
|
+
return this;
|
|
16232
|
+
}
|
|
16233
|
+
};
|
|
16234
|
+
}
|
|
16235
|
+
function createTripwireRun(args) {
|
|
16236
|
+
const id = globalThis.crypto.randomUUID();
|
|
16237
|
+
const result = {
|
|
16238
|
+
id,
|
|
16239
|
+
status: "cancelled",
|
|
16240
|
+
tripwire: args.tripwire,
|
|
16241
|
+
...args.model !== void 0 ? { model: args.model } : {}
|
|
16242
|
+
};
|
|
16243
|
+
const run = {
|
|
16244
|
+
id,
|
|
16245
|
+
agentId: args.agentId,
|
|
16246
|
+
status: "cancelled",
|
|
16247
|
+
...args.model !== void 0 ? { model: args.model } : {},
|
|
16248
|
+
stream: () => emptyStream(),
|
|
16249
|
+
wait: () => Promise.resolve(result),
|
|
16250
|
+
cancel: () => Promise.resolve(),
|
|
16251
|
+
conversation: () => Promise.resolve([]),
|
|
16252
|
+
supports: (op) => SUPPORTED.has(op),
|
|
16253
|
+
unsupportedReason: (op) => SUPPORTED.has(op) ? void 0 : `operation "${op}" is not available on a tripwire run`,
|
|
16254
|
+
onDidChangeStatus: () => () => {
|
|
16255
|
+
}
|
|
16256
|
+
// already terminal — status never changes
|
|
16257
|
+
};
|
|
16258
|
+
registerRun(run);
|
|
16259
|
+
return run;
|
|
16260
|
+
}
|
|
16261
|
+
|
|
16262
|
+
// src/internal/runtime/processors/wrap-output-run.ts
|
|
16263
|
+
function wrapRunWithOutputProcessors(args) {
|
|
16264
|
+
if (args.processors.length === 0) return args.run;
|
|
16265
|
+
const compute = async () => {
|
|
16266
|
+
const result = await args.run.wait();
|
|
16267
|
+
if (result.status !== "finished" || result.result === void 0) return result;
|
|
16268
|
+
const res = await runOutputProcessors(args.processors, result.result, args.agentId);
|
|
16269
|
+
if (res.kind === "ok") return { ...result, result: res.value };
|
|
16270
|
+
emitRunEvent(args.onRunEvent, {
|
|
16271
|
+
type: "tripwire",
|
|
16272
|
+
reason: res.tripwire.reason,
|
|
16273
|
+
processorId: res.tripwire.processorId
|
|
16274
|
+
});
|
|
16275
|
+
const { result: _suppressed, ...metadata } = result;
|
|
16276
|
+
return { ...metadata, status: "cancelled", tripwire: res.tripwire };
|
|
16277
|
+
};
|
|
16278
|
+
let processed;
|
|
16279
|
+
const wrappedWait = () => {
|
|
16280
|
+
processed ??= compute();
|
|
16281
|
+
return processed;
|
|
16282
|
+
};
|
|
16283
|
+
return new Proxy(args.run, {
|
|
16284
|
+
get(target, prop, receiver) {
|
|
16285
|
+
if (prop === "wait") return wrappedWait;
|
|
16286
|
+
return Reflect.get(target, prop, receiver);
|
|
16287
|
+
}
|
|
16288
|
+
});
|
|
16289
|
+
}
|
|
16290
|
+
|
|
16079
16291
|
// src/internal/runtime/local-agent/local-agent-memory-hooks.ts
|
|
16080
16292
|
var DEFAULT_MAX_RECALL_BYTES = 16e3;
|
|
16081
16293
|
async function applyPreUserSendHook(args) {
|
|
@@ -16123,11 +16335,38 @@ function wrapRunWithPostReplyHook(args) {
|
|
|
16123
16335
|
}
|
|
16124
16336
|
|
|
16125
16337
|
// src/internal/runtime/local-agent/local-agent-send.ts
|
|
16338
|
+
async function applyInputProcessors(inputs, message, rawUserText, options, sendModel) {
|
|
16339
|
+
const processors = inputs.options.inputProcessors;
|
|
16340
|
+
if (processors === void 0 || processors.length === 0) {
|
|
16341
|
+
return { userText: rawUserText, effectiveMessage: message };
|
|
16342
|
+
}
|
|
16343
|
+
const res = await runInputProcessors(processors, rawUserText, inputs.agentId);
|
|
16344
|
+
if (res.kind === "tripwire") {
|
|
16345
|
+
emitRunEvent(options.onRunEvent, {
|
|
16346
|
+
type: "tripwire",
|
|
16347
|
+
reason: res.tripwire.reason,
|
|
16348
|
+
processorId: res.tripwire.processorId
|
|
16349
|
+
});
|
|
16350
|
+
return {
|
|
16351
|
+
tripwireRun: createTripwireRun({
|
|
16352
|
+
agentId: inputs.agentId,
|
|
16353
|
+
tripwire: res.tripwire,
|
|
16354
|
+
model: sendModel
|
|
16355
|
+
})
|
|
16356
|
+
};
|
|
16357
|
+
}
|
|
16358
|
+
const effectiveMessage = typeof message === "string" ? res.value : { ...message, text: res.value };
|
|
16359
|
+
return { userText: res.value, effectiveMessage };
|
|
16360
|
+
}
|
|
16126
16361
|
async function executeSendLocked(inputs, message, options) {
|
|
16127
16362
|
if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
|
|
16128
16363
|
await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
|
|
16129
|
-
|
|
16130
|
-
|
|
16364
|
+
const sendModel = normalizeModel(options.model);
|
|
16365
|
+
inputs.applyModelOverride(sendModel);
|
|
16366
|
+
const rawUserText = typeof message === "string" ? message : message.text;
|
|
16367
|
+
const gated = await applyInputProcessors(inputs, message, rawUserText, options, sendModel);
|
|
16368
|
+
if ("tripwireRun" in gated) return gated.tripwireRun;
|
|
16369
|
+
const { userText, effectiveMessage } = gated;
|
|
16131
16370
|
if (inputs.options.onBeforeSend !== void 0) {
|
|
16132
16371
|
await inputs.options.onBeforeSend({
|
|
16133
16372
|
conversationId: inputs.agentId,
|
|
@@ -16139,7 +16378,7 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
16139
16378
|
pluginManager: inputs.pluginManagerCode,
|
|
16140
16379
|
agentId: inputs.agentId,
|
|
16141
16380
|
options: inputs.options,
|
|
16142
|
-
original:
|
|
16381
|
+
original: effectiveMessage,
|
|
16143
16382
|
userText,
|
|
16144
16383
|
sendOptions: options
|
|
16145
16384
|
});
|
|
@@ -16177,11 +16416,18 @@ async function executeSendLocked(inputs, message, options) {
|
|
|
16177
16416
|
memoryTools,
|
|
16178
16417
|
effectiveMemoryProvider
|
|
16179
16418
|
);
|
|
16419
|
+
const outputProcessors = inputs.options.outputProcessors;
|
|
16420
|
+
const processedRun = outputProcessors !== void 0 && outputProcessors.length > 0 ? wrapRunWithOutputProcessors({
|
|
16421
|
+
run,
|
|
16422
|
+
processors: outputProcessors,
|
|
16423
|
+
agentId: inputs.agentId,
|
|
16424
|
+
onRunEvent: options.onRunEvent
|
|
16425
|
+
}) : run;
|
|
16180
16426
|
return wrapRunWithPostReplyHook({
|
|
16181
16427
|
pluginManager: inputs.pluginManagerCode,
|
|
16182
16428
|
agentId: inputs.agentId,
|
|
16183
16429
|
options: inputs.options,
|
|
16184
|
-
run,
|
|
16430
|
+
run: processedRun,
|
|
16185
16431
|
userText
|
|
16186
16432
|
});
|
|
16187
16433
|
}
|
|
@@ -16430,7 +16676,7 @@ var LocalAgent = class {
|
|
|
16430
16676
|
}
|
|
16431
16677
|
// biome-ignore format: G8 budget — thin accessor for the assembly inputs.
|
|
16432
16678
|
assemblyInputs() {
|
|
16433
|
-
return { agentId: this.agentId, workspaceCwd: this.workspaceCwd, model: this.model, options: this.options, context: this.context, skillsManager: this.skillsManager, systemPromptPipeline: this.systemPromptPipeline };
|
|
16679
|
+
return { agentId: this.agentId, workspaceCwd: this.workspaceCwd, model: this.model, options: this.options, context: this.context, skillsManager: this.skillsManager, settingSourcesIncludeProject: this.settingSourcesIncludeProject, systemPromptPipeline: this.systemPromptPipeline };
|
|
16434
16680
|
}
|
|
16435
16681
|
async resolveSystemPrompt(userText, options, memoryFacts) {
|
|
16436
16682
|
const base = await resolveSystemPromptForSend(
|