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