@theokit/sdk 4.28.0 → 4.29.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/dist/{cron-BN6JJlDw.d.ts → agent-BZz4X8ZM.d.ts} +2 -577
- package/dist/{cron-CoQREV_k.d.cts → agent-CdjSCbYz.d.cts} +2 -577
- package/dist/agent-FBTLZI6V.js +41 -0
- package/dist/agent-FBTLZI6V.js.map +1 -0
- package/dist/agent-LBCEK6VH.cjs +50 -0
- package/dist/agent-LBCEK6VH.cjs.map +1 -0
- package/dist/{chunk-I53QDJVI.cjs → chunk-54YLX4Q6.cjs} +5 -5
- package/dist/{chunk-I53QDJVI.cjs.map → chunk-54YLX4Q6.cjs.map} +1 -1
- package/dist/{chunk-AKSBP7OO.js → chunk-5IB2UKSN.js} +5 -41
- package/dist/chunk-5IB2UKSN.js.map +1 -0
- package/dist/chunk-BNIFFFH3.js +129 -0
- package/dist/chunk-BNIFFFH3.js.map +1 -0
- package/dist/{chunk-LSLPF6OI.cjs → chunk-DHLZIMP6.cjs} +5 -43
- package/dist/chunk-DHLZIMP6.cjs.map +1 -0
- package/dist/{chunk-PF5Y5BHG.js → chunk-EULKRTB5.js} +3 -3
- package/dist/{chunk-PF5Y5BHG.js.map → chunk-EULKRTB5.js.map} +1 -1
- package/dist/chunk-FKCC2MED.js +43 -0
- package/dist/chunk-FKCC2MED.js.map +1 -0
- package/dist/{chunk-QUTUJ6P6.cjs → chunk-HK7ZHSAX.cjs} +25 -16
- package/dist/chunk-HK7ZHSAX.cjs.map +1 -0
- package/dist/{chunk-MQLCZ4HJ.cjs → chunk-JLMXKTBX.cjs} +4 -4
- package/dist/{chunk-MQLCZ4HJ.cjs.map → chunk-JLMXKTBX.cjs.map} +1 -1
- package/dist/chunk-LALRCFSN.cjs +46 -0
- package/dist/chunk-LALRCFSN.cjs.map +1 -0
- package/dist/{chunk-DUK5WMKJ.js → chunk-R6ZP6KNB.js} +25 -16
- package/dist/chunk-R6ZP6KNB.js.map +1 -0
- package/dist/chunk-RZQ6E5YZ.cjs +131 -0
- package/dist/chunk-RZQ6E5YZ.cjs.map +1 -0
- package/dist/{chunk-XW6RXVGB.js → chunk-VUJ3NVDC.js} +691 -807
- package/dist/chunk-VUJ3NVDC.js.map +1 -0
- package/dist/{chunk-G6GO6BXD.js → chunk-XAUBQMQU.js} +3 -3
- package/dist/{chunk-G6GO6BXD.js.map → chunk-XAUBQMQU.js.map} +1 -1
- package/dist/{chunk-PN53WGEI.cjs → chunk-YQAPEYUV.cjs} +714 -830
- package/dist/chunk-YQAPEYUV.cjs.map +1 -0
- package/dist/compact-session-OO2GD76G.js +1 -1
- package/dist/compact-session-OO7NVWPB.cjs +1 -1
- package/dist/cron-CIIshMs3.d.cts +579 -0
- package/dist/cron-dElBjDaL.d.ts +579 -0
- package/dist/cron.cjs +13 -11
- package/dist/cron.d.cts +2 -1
- package/dist/cron.d.ts +2 -1
- package/dist/cron.js +12 -10
- package/dist/eval.cjs +17 -15
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +13 -11
- package/dist/eval.js.map +1 -1
- package/dist/{index-manager-CB6I7XFQ.cjs → index-manager-H7HUMW52.cjs} +5 -5
- package/dist/{index-manager-CB6I7XFQ.cjs.map → index-manager-H7HUMW52.cjs.map} +1 -1
- package/dist/{index-manager-L27Q3QAC.js → index-manager-P7ZUX2RG.js} +4 -4
- package/dist/{index-manager-L27Q3QAC.js.map → index-manager-P7ZUX2RG.js.map} +1 -1
- package/dist/index.cjs +65 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -4
- package/dist/index.d.ts +18 -4
- package/dist/index.js +41 -20
- package/dist/index.js.map +1 -1
- package/dist/internal/persistence/index.cjs +10 -10
- package/dist/internal/persistence/index.js +2 -2
- package/dist/internal/persistence/jsonl.d.cts +7 -0
- package/dist/internal/persistence/jsonl.d.ts +7 -0
- package/dist/internal/persistence/session-writer.d.cts +56 -0
- package/dist/internal/persistence/session-writer.d.ts +56 -0
- package/dist/internal/persistence/transcript-ops.d.cts +71 -0
- package/dist/internal/persistence/transcript-ops.d.ts +71 -0
- package/dist/persistence.cjs +115 -12
- package/dist/persistence.cjs.map +1 -1
- package/dist/persistence.d.cts +2 -0
- package/dist/persistence.d.ts +2 -0
- package/dist/persistence.js +105 -3
- package/dist/persistence.js.map +1 -1
- package/dist/skills.cjs +4 -3
- package/dist/skills.js +2 -1
- package/dist/subagents-loader.cjs +19 -0
- package/dist/subagents-loader.cjs.map +1 -0
- package/dist/subagents-loader.d.cts +39 -0
- package/dist/subagents-loader.d.ts +39 -0
- package/dist/subagents-loader.js +16 -0
- package/dist/subagents-loader.js.map +1 -0
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.js +1 -1
- package/package.json +12 -2
- package/dist/chunk-AKSBP7OO.js.map +0 -1
- package/dist/chunk-DUK5WMKJ.js.map +0 -1
- package/dist/chunk-LSLPF6OI.cjs.map +0 -1
- package/dist/chunk-PN53WGEI.cjs.map +0 -1
- package/dist/chunk-QUTUJ6P6.cjs.map +0 -1
- package/dist/chunk-XW6RXVGB.js.map +0 -1
|
@@ -24,26 +24,35 @@ function tryParseObjectLine(line) {
|
|
|
24
24
|
return isPlainObject(parsed) ? parsed : void 0;
|
|
25
25
|
}
|
|
26
26
|
function loadJsonl(path, opts = {}) {
|
|
27
|
-
const
|
|
27
|
+
const linhas = readFileSync(path, "utf8").split("\n");
|
|
28
28
|
const out = [];
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const line = rawLine.trim();
|
|
29
|
+
for (let i = 0; i < linhas.length; i += 1) {
|
|
30
|
+
const lineNumber = i + 1;
|
|
31
|
+
const line = (linhas[i] ?? "").trim();
|
|
33
32
|
if (line.length === 0) continue;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!isPlainObject(parsed)) {
|
|
41
|
-
throw new JsonlParseError(`line ${lineNumber}: not a JSON object`, lineNumber);
|
|
42
|
-
}
|
|
33
|
+
const parsed = parsearLinha(
|
|
34
|
+
line,
|
|
35
|
+
lineNumber,
|
|
36
|
+
opts.tolerateTrailingPartialLine === true && lineNumber === linhas.length
|
|
37
|
+
);
|
|
38
|
+
if (parsed === void 0) break;
|
|
43
39
|
out.push(opts.map ? opts.map(parsed, lineNumber) : parsed);
|
|
44
40
|
}
|
|
45
41
|
return out;
|
|
46
42
|
}
|
|
43
|
+
function parsearLinha(line, lineNumber, tolerar) {
|
|
44
|
+
let parsed;
|
|
45
|
+
try {
|
|
46
|
+
parsed = JSON.parse(line);
|
|
47
|
+
} catch {
|
|
48
|
+
if (tolerar) return void 0;
|
|
49
|
+
throw new JsonlParseError(`line ${lineNumber}: invalid JSON`, lineNumber);
|
|
50
|
+
}
|
|
51
|
+
if (!isPlainObject(parsed)) {
|
|
52
|
+
throw new JsonlParseError(`line ${lineNumber}: not a JSON object`, lineNumber);
|
|
53
|
+
}
|
|
54
|
+
return parsed;
|
|
55
|
+
}
|
|
47
56
|
function appendJsonl(path, record) {
|
|
48
57
|
mkdirSync(dirname(path), { recursive: true });
|
|
49
58
|
appendFileSync(path, `${JSON.stringify(record)}
|
|
@@ -67,5 +76,5 @@ function readJsonlIds(path, keyFn) {
|
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
export { JsonlParseError, appendJsonl, loadJsonl, readJsonlIds };
|
|
70
|
-
//# sourceMappingURL=chunk-
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-R6ZP6KNB.js.map
|
|
80
|
+
//# sourceMappingURL=chunk-R6ZP6KNB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/persistence/jsonl.ts"],"names":[],"mappings":"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","file":"chunk-R6ZP6KNB.js","sourcesContent":["/**\n * Durable JSONL primitives shared by the eval harness (M6).\n *\n * - `loadJsonl` — generic dataset reader (split/trim/skip-blank/parse) with a\n * line-numbered {@link JsonlParseError}. The dataset SCHEMA is the caller's\n * concern via `map` (M6 ADR D3) — this module owns only the parse.\n * - `appendJsonl` / `readJsonlIds` — crash-durable, resumable batch persistence\n * (M6 ADR D1): each record is appended as one whole `\\n`-terminated line the\n * instant it is produced, and a re-run resumes by skipping already-keyed rows.\n *\n * referencia: knowledge-base/references/theocode-eval/lib/swebench-dataset.ts:82\n * (parseJsonl + line-N error) and swebench-batch.ts:113,205 (resume + per-line\n * flush).\n *\n * @internal\n */\nimport { appendFileSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/** Raised when a JSONL line is not valid JSON or is not a JSON object. Carries the 1-based line number. */\nexport class JsonlParseError extends Error {\n constructor(\n message: string,\n readonly line: number,\n ) {\n super(message);\n this.name = \"JsonlParseError\";\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Parse a single trimmed line to a plain object, or `undefined` if blank / invalid / non-object. */\nfunction tryParseObjectLine(line: string): Record<string, unknown> | undefined {\n if (line.length === 0) return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n return undefined;\n }\n return isPlainObject(parsed) ? parsed : undefined;\n}\n\n/**\n * Parse a JSONL file into rows. Blank lines are skipped. A malformed or\n * non-object line throws {@link JsonlParseError} naming the 1-based line. When\n * `map` is provided, each raw object is mapped to the typed row (the SWE-bench\n * schema lives in the caller's `map`, per M6 ADR D3).\n */\nexport function loadJsonl<T = Record<string, unknown>>(\n path: string,\n opts: {\n map?: (raw: Record<string, unknown>, lineNumber: number) => T;\n /**\n * M81 — tolerate a truncated LAST line (a crash artifact: the process died mid-write).\n *\n * Opt-in on purpose. As a default it would also swallow corruption in the MIDDLE of the file,\n * turning loud data loss into silent data loss — the wrong trade for a session store.\n */\n tolerateTrailingPartialLine?: boolean;\n } = {},\n): T[] {\n const linhas = readFileSync(path, \"utf8\").split(\"\\n\");\n const out: T[] = [];\n for (let i = 0; i < linhas.length; i += 1) {\n const lineNumber = i + 1;\n const line = (linhas[i] ?? \"\").trim();\n if (line.length === 0) continue;\n // M81 — `undefined` = linha inválida tolerada (última, truncada por crash). Qualquer outra\n // linha inválida já lançou dentro de `parsearLinha`.\n const parsed = parsearLinha(\n line,\n lineNumber,\n opts.tolerateTrailingPartialLine === true && lineNumber === linhas.length,\n );\n if (parsed === undefined) break;\n out.push(opts.map ? opts.map(parsed, lineNumber) : (parsed as unknown as T));\n }\n return out;\n}\n\n/**\n * Parse de UMA linha, devolvendo `undefined` quando ela é uma última-linha-truncada tolerada.\n *\n * Extraído porque `loadJsonl` passou do teto de complexidade cognitiva quando ganhou a tolerância —\n * e porque parse-de-linha e iteração-do-arquivo são duas responsabilidades que só estavam juntas\n * por hábito.\n */\nfunction parsearLinha(\n line: string,\n lineNumber: number,\n tolerar: boolean,\n): Record<string, unknown> | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n if (tolerar) return undefined;\n throw new JsonlParseError(`line ${lineNumber}: invalid JSON`, lineNumber);\n }\n if (!isPlainObject(parsed)) {\n throw new JsonlParseError(`line ${lineNumber}: not a JSON object`, lineNumber);\n }\n return parsed;\n}\n\n/**\n * Append one record as a whole `\\n`-terminated JSON line. Creates the parent dir\n * if missing. `appendFileSync` is synchronous, so within a single Node process\n * the event loop serializes writes and each call writes its line atomically —\n * interleave-safe for the bounded-concurrency batch runner.\n *\n * referencia: swebench-batch.ts:192 (mkdir-before-append), :205 (per-line flush).\n */\nexport function appendJsonl(path: string, record: unknown): void {\n mkdirSync(dirname(path), { recursive: true });\n appendFileSync(path, `${JSON.stringify(record)}\\n`);\n}\n\n/**\n * Read the set of keys from an existing JSONL file for which `keyFn(parsed)`\n * returns a non-empty string. Used to resume a crashed batch by skipping rows\n * already persisted with a successful result. A trailing partial line from an\n * interrupted append is tolerated (skipped, not thrown), and a missing file\n * yields an empty set.\n *\n * referencia: swebench-batch.ts:113 (readDoneIds), :129 (success-only),\n * :131 (tolerate partial line).\n */\nexport function readJsonlIds(\n path: string,\n keyFn: (parsed: Record<string, unknown>) => string | undefined,\n): Set<string> {\n const done = new Set<string>();\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return done; // no file yet → nothing done\n }\n for (const rawLine of text.split(\"\\n\")) {\n // A trailing partial line from an interrupted run parses to undefined → skipped.\n const parsed = tryParseObjectLine(rawLine.trim());\n if (parsed === undefined) continue;\n const key = keyFn(parsed);\n if (typeof key === \"string\" && key.length > 0) done.add(key);\n }\n return done;\n}\n"]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkLALRCFSN_cjs = require('./chunk-LALRCFSN.cjs');
|
|
4
|
+
var chunkA44COQJJ_cjs = require('./chunk-A44COQJJ.cjs');
|
|
5
|
+
var promises = require('fs/promises');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
|
|
8
|
+
async function loadSubagents(cwd, settingSourcesIncludeProject, inline) {
|
|
9
|
+
const result = {};
|
|
10
|
+
if (settingSourcesIncludeProject) {
|
|
11
|
+
const projectAgents = await readProjectSubagents(cwd);
|
|
12
|
+
for (const [name, definition] of Object.entries(projectAgents)) {
|
|
13
|
+
result[name] = definition;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (inline !== void 0) {
|
|
17
|
+
for (const [name, definition] of Object.entries(inline)) {
|
|
18
|
+
result[name] = definition;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
async function readProjectSubagents(cwd) {
|
|
24
|
+
const root = path.join(cwd, ".theokit", "agents");
|
|
25
|
+
const entries = await chunkLALRCFSN_cjs.readWorkspaceDir(root, "subagents_read_error", "subagents directory");
|
|
26
|
+
const subagents = {};
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
29
|
+
const path$1 = path.join(root, entry.name);
|
|
30
|
+
const raw = await promises.readFile(path$1, "utf8");
|
|
31
|
+
const definition = parseSubagentMarkdown(raw, entry.name);
|
|
32
|
+
subagents[definition.name] = definition.definition;
|
|
33
|
+
}
|
|
34
|
+
return subagents;
|
|
35
|
+
}
|
|
36
|
+
var ACCEPTED_FIELDS = /* @__PURE__ */ new Set([
|
|
37
|
+
"name",
|
|
38
|
+
"description",
|
|
39
|
+
"model",
|
|
40
|
+
"tools",
|
|
41
|
+
"reasoning_effort",
|
|
42
|
+
"mcp",
|
|
43
|
+
"sandbox"
|
|
44
|
+
]);
|
|
45
|
+
function parseSubagentMarkdown(raw, filename) {
|
|
46
|
+
const { frontmatter, body } = splitFrontmatter(raw, filename);
|
|
47
|
+
const fields = parseFrontmatterFields(frontmatter);
|
|
48
|
+
rejectUnknownFields(fields, filename);
|
|
49
|
+
rejectMcp(fields, filename);
|
|
50
|
+
const definition = {
|
|
51
|
+
description: asString(fields.description) ?? "",
|
|
52
|
+
prompt: body
|
|
53
|
+
};
|
|
54
|
+
const model = resolveModel(fields, filename);
|
|
55
|
+
if (model !== void 0) definition.model = model;
|
|
56
|
+
const tools = toStringList(fields.tools);
|
|
57
|
+
if (tools.length > 0) definition.tools = tools;
|
|
58
|
+
const sandbox = resolveSandbox(fields, filename);
|
|
59
|
+
if (sandbox !== void 0) definition.sandbox = sandbox;
|
|
60
|
+
const name = asString(fields.name) ?? filename.replace(/\.md$/, "");
|
|
61
|
+
return { name, definition };
|
|
62
|
+
}
|
|
63
|
+
function rejectUnknownFields(fields, filename) {
|
|
64
|
+
for (const key of Object.keys(fields)) {
|
|
65
|
+
if (!ACCEPTED_FIELDS.has(key)) {
|
|
66
|
+
throw new chunkA44COQJJ_cjs.ConfigurationError(
|
|
67
|
+
`Subagent ${filename}: unknown frontmatter field "${key}" (accepted: ${[...ACCEPTED_FIELDS].join(", ")})`,
|
|
68
|
+
{ code: "subagent_unknown_field" }
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function rejectMcp(fields, filename) {
|
|
74
|
+
if (fields.mcp !== void 0) {
|
|
75
|
+
throw new chunkA44COQJJ_cjs.ConfigurationError(
|
|
76
|
+
`Subagent ${filename}: per-subagent "mcp" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,
|
|
77
|
+
{ code: "subagent_mcp_unsupported_local" }
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function resolveModel(fields, filename) {
|
|
82
|
+
const modelId = asString(fields.model);
|
|
83
|
+
const effort = asString(fields.reasoning_effort);
|
|
84
|
+
if (effort !== void 0 && (modelId === void 0 || modelId === "inherit")) {
|
|
85
|
+
throw new chunkA44COQJJ_cjs.ConfigurationError(
|
|
86
|
+
`Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or "inherit" cannot carry it)`,
|
|
87
|
+
{ code: "subagent_reasoning_effort_without_model" }
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (modelId === void 0) return void 0;
|
|
91
|
+
if (modelId === "inherit") return "inherit";
|
|
92
|
+
return effort !== void 0 ? { id: modelId, params: [{ id: "thinking", value: effort }] } : { id: modelId };
|
|
93
|
+
}
|
|
94
|
+
function resolveSandbox(fields, filename) {
|
|
95
|
+
if (fields.sandbox === void 0) return void 0;
|
|
96
|
+
if (typeof fields.sandbox !== "boolean") {
|
|
97
|
+
throw new chunkA44COQJJ_cjs.ConfigurationError(
|
|
98
|
+
`Subagent ${filename}: sandbox must be a boolean (got "${String(fields.sandbox)}"); granular sandbox modes are not supported by the runtime`,
|
|
99
|
+
{ code: "subagent_sandbox_not_boolean" }
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return fields.sandbox;
|
|
103
|
+
}
|
|
104
|
+
function asString(v) {
|
|
105
|
+
if (typeof v !== "string") return void 0;
|
|
106
|
+
const m = /^(["'])(.*)\1$/.exec(v);
|
|
107
|
+
return m ? m[2] : v;
|
|
108
|
+
}
|
|
109
|
+
function toStringList(v) {
|
|
110
|
+
if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);
|
|
111
|
+
if (typeof v === "string") {
|
|
112
|
+
return v.split(/[\s,]+/).map((t) => t.trim()).filter((t) => t.length > 0);
|
|
113
|
+
}
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
function splitFrontmatter(raw, filename) {
|
|
117
|
+
const match = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/.exec(raw);
|
|
118
|
+
if (match === null) {
|
|
119
|
+
throw new chunkA44COQJJ_cjs.ConfigurationError(`Subagent ${filename} is missing frontmatter`, {
|
|
120
|
+
code: "subagent_missing_frontmatter"
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return { frontmatter: match[1] ?? "", body: (match[2] ?? "").trim() };
|
|
124
|
+
}
|
|
125
|
+
function parseFrontmatterFields(frontmatter) {
|
|
126
|
+
return chunkLALRCFSN_cjs.parseSimpleYaml(frontmatter);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
exports.loadSubagents = loadSubagents;
|
|
130
|
+
//# sourceMappingURL=chunk-RZQ6E5YZ.cjs.map
|
|
131
|
+
//# sourceMappingURL=chunk-RZQ6E5YZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/runtime/skills/subagents-loader.ts"],"names":["join","readWorkspaceDir","path","readFile","ConfigurationError","parseSimpleYaml"],"mappings":";;;;;;;AAkBA,eAAsB,aAAA,CACpB,GAAA,EACA,4BAAA,EACA,MAAA,EAC0C;AAC1C,EAAA,MAAM,SAA0C,EAAC;AACjD,EAAA,IAAI,4BAAA,EAA8B;AAChC,IAAA,MAAM,aAAA,GAAgB,MAAM,oBAAA,CAAqB,GAAG,CAAA;AACpD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,EAAG;AAC9D,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI,UAAA;AAAA,IACjB;AAAA,EACF;AACA,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACvD,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI,UAAA;AAAA,IACjB;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,qBAAqB,GAAA,EAAuD;AACzF,EAAA,MAAM,IAAA,GAAOA,SAAA,CAAK,GAAA,EAAK,UAAA,EAAY,QAAQ,CAAA;AAC3C,EAAA,MAAM,OAAA,GAAU,MAAMC,kCAAA,CAAiB,IAAA,EAAM,wBAAwB,qBAAqB,CAAA;AAC1F,EAAA,MAAM,YAA6C,EAAC;AACpD,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,IAAI,CAAC,MAAM,MAAA,EAAO,IAAK,CAAC,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,KAAK,CAAA,EAAG;AACpD,IAAA,MAAMC,MAAA,GAAOF,SAAA,CAAK,IAAA,EAAM,KAAA,CAAM,IAAI,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,MAAMG,iBAAA,CAASD,MAAA,EAAM,MAAM,CAAA;AACvC,IAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,GAAA,EAAK,KAAA,CAAM,IAAI,CAAA;AACxD,IAAA,SAAA,CAAU,UAAA,CAAW,IAAI,CAAA,GAAI,UAAA,CAAW,UAAA;AAAA,EAC1C;AACA,EAAA,OAAO,SAAA;AACT;AAKA,IAAM,eAAA,uBAAsB,GAAA,CAAI;AAAA,EAC9B,MAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,kBAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,qBAAA,CACP,KACA,QAAA,EAC+C;AAC/C,EAAA,MAAM,EAAE,WAAA,EAAa,IAAA,EAAK,GAAI,gBAAA,CAAiB,KAAK,QAAQ,CAAA;AAC5D,EAAA,MAAM,MAAA,GAAS,uBAAuB,WAAW,CAAA;AACjD,EAAA,mBAAA,CAAoB,QAAQ,QAAQ,CAAA;AACpC,EAAA,SAAA,CAAU,QAAQ,QAAQ,CAAA;AAE1B,EAAA,MAAM,UAAA,GAA8B;AAAA,IAClC,WAAA,EAAa,QAAA,CAAS,MAAA,CAAO,WAAW,CAAA,IAAK,EAAA;AAAA,IAC7C,MAAA,EAAQ;AAAA,GACV;AACA,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,MAAA,EAAQ,QAAQ,CAAA;AAC3C,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,UAAA,CAAW,KAAA,GAAQ,KAAA;AAC5C,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,MAAA,CAAO,KAAK,CAAA;AACvC,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,UAAA,CAAW,KAAA,GAAQ,KAAA;AACzC,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,MAAA,EAAQ,QAAQ,CAAA;AAC/C,EAAA,IAAI,OAAA,KAAY,MAAA,EAAW,UAAA,CAAW,OAAA,GAAU,OAAA;AAEhD,EAAA,MAAM,IAAA,GAAO,SAAS,MAAA,CAAO,IAAI,KAAK,QAAA,CAAS,OAAA,CAAQ,SAAS,EAAE,CAAA;AAClE,EAAA,OAAO,EAAE,MAAM,UAAA,EAAW;AAC5B;AAEA,SAAS,mBAAA,CACP,QACA,QAAA,EACM;AACN,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AACrC,IAAA,IAAI,CAAC,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC7B,MAAA,MAAM,IAAIE,oCAAA;AAAA,QACR,CAAA,SAAA,EAAY,QAAQ,CAAA,6BAAA,EAAgC,GAAG,CAAA,aAAA,EAAgB,CAAC,GAAG,eAAe,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,QACtG,EAAE,MAAM,wBAAA;AAAyB,OACnC;AAAA,IACF;AAAA,EACF;AACF;AAOA,SAAS,SAAA,CAAU,QAAsD,QAAA,EAAwB;AAC/F,EAAA,IAAI,MAAA,CAAO,QAAQ,MAAA,EAAW;AAC5B,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,YAAY,QAAQ,CAAA,wIAAA,CAAA;AAAA,MACpB,EAAE,MAAM,gCAAA;AAAiC,KAC3C;AAAA,EACF;AACF;AAKA,SAAS,YAAA,CACP,QACA,QAAA,EACwC;AACxC,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AACrC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,MAAA,CAAO,gBAAgB,CAAA;AAI/C,EAAA,IAAI,MAAA,KAAW,MAAA,KAAc,OAAA,KAAY,MAAA,IAAa,YAAY,SAAA,CAAA,EAAY;AAC5E,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,YAAY,QAAQ,CAAA,wHAAA,CAAA;AAAA,MACpB,EAAE,MAAM,yCAAA;AAA0C,KACpD;AAAA,EACF;AACA,EAAA,IAAI,OAAA,KAAY,QAAW,OAAO,MAAA;AAClC,EAAA,IAAI,OAAA,KAAY,WAAW,OAAO,SAAA;AAClC,EAAA,OAAO,WAAW,MAAA,GACd,EAAE,EAAA,EAAI,OAAA,EAAS,QAAQ,CAAC,EAAE,EAAA,EAAI,UAAA,EAAY,OAAO,MAAA,EAAQ,GAAE,GAC3D,EAAE,IAAI,OAAA,EAAQ;AACpB;AAIA,SAAS,cAAA,CACP,QACA,QAAA,EACqB;AACrB,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,MAAA,EAAW,OAAO,MAAA;AACzC,EAAA,IAAI,OAAO,MAAA,CAAO,OAAA,KAAY,SAAA,EAAW;AACvC,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,YAAY,QAAQ,CAAA,kCAAA,EAAqC,MAAA,CAAO,MAAA,CAAO,OAAO,CAAC,CAAA,2DAAA,CAAA;AAAA,MAC/E,EAAE,MAAM,8BAAA;AAA+B,KACzC;AAAA,EACF;AACA,EAAA,OAAO,MAAA,CAAO,OAAA;AAChB;AAEA,SAAS,SAAS,CAAA,EAAqD;AACrE,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,MAAA;AAIlC,EAAA,MAAM,CAAA,GAAI,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAA;AACjC,EAAA,OAAO,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA;AACpB;AAGA,SAAS,aAAa,CAAA,EAA2C;AAC/D,EAAA,IAAI,MAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9E,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU;AACzB,IAAA,OAAO,EACJ,KAAA,CAAM,QAAQ,CAAA,CACd,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,EACnB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,EAAC;AACV;AAEA,SAAS,gBAAA,CAAiB,KAAa,QAAA,EAAyD;AAC9F,EAAA,MAAM,KAAA,GAAQ,yCAAA,CAA0C,IAAA,CAAK,GAAG,CAAA;AAChE,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,MAAM,IAAIA,oCAAA,CAAmB,CAAA,SAAA,EAAY,QAAQ,CAAA,uBAAA,CAAA,EAA2B;AAAA,MAC1E,IAAA,EAAM;AAAA,KACP,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,WAAA,EAAa,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA,EAAI,IAAA,EAAA,CAAO,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA,EAAI,IAAA,EAAK,EAAE;AACtE;AAEA,SAAS,uBAAuB,WAAA,EAAmE;AAIjG,EAAA,OAAOC,kCAAgB,WAAW,CAAA;AACpC","file":"chunk-RZQ6E5YZ.cjs","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport type { AgentDefinition } from \"../../../types/agent.js\";\nimport type { ModelSelection } from \"../../../types/agent-prims.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\n\n/**\n * Load file-based subagents from `.theokit/agents/*.md` and merge with\n * inline definitions. Inline overrides file-based on name conflict.\n *\n * Each markdown file has YAML frontmatter (description + optional model)\n * and a body that becomes the subagent prompt.\n *\n * @internal\n */\nexport async function loadSubagents(\n cwd: string,\n settingSourcesIncludeProject: boolean,\n inline: Record<string, AgentDefinition> | undefined,\n): Promise<Record<string, AgentDefinition>> {\n const result: Record<string, AgentDefinition> = {};\n if (settingSourcesIncludeProject) {\n const projectAgents = await readProjectSubagents(cwd);\n for (const [name, definition] of Object.entries(projectAgents)) {\n result[name] = definition;\n }\n }\n if (inline !== undefined) {\n for (const [name, definition] of Object.entries(inline)) {\n result[name] = definition;\n }\n }\n return result;\n}\n\nasync function readProjectSubagents(cwd: string): Promise<Record<string, AgentDefinition>> {\n const root = join(cwd, \".theokit\", \"agents\");\n const entries = await readWorkspaceDir(root, \"subagents_read_error\", \"subagents directory\");\n const subagents: Record<string, AgentDefinition> = {};\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const path = join(root, entry.name);\n const raw = await readFile(path, \"utf8\");\n const definition = parseSubagentMarkdown(raw, entry.name);\n subagents[definition.name] = definition.definition;\n }\n return subagents;\n}\n\n// The frontmatter keys a disk subagent may declare. Any other key is a typed load\n// error rather than a silent drop — a dropped `sandbox` an operator wrote believing\n// it confines the child is exactly the silent-gate failure class this guards against.\nconst ACCEPTED_FIELDS = new Set([\n \"name\",\n \"description\",\n \"model\",\n \"tools\",\n \"reasoning_effort\",\n \"mcp\",\n \"sandbox\",\n]);\n\nfunction parseSubagentMarkdown(\n raw: string,\n filename: string,\n): { name: string; definition: AgentDefinition } {\n const { frontmatter, body } = splitFrontmatter(raw, filename);\n const fields = parseFrontmatterFields(frontmatter);\n rejectUnknownFields(fields, filename);\n rejectMcp(fields, filename);\n\n const definition: AgentDefinition = {\n description: asString(fields.description) ?? \"\",\n prompt: body,\n };\n const model = resolveModel(fields, filename);\n if (model !== undefined) definition.model = model;\n const tools = toStringList(fields.tools);\n if (tools.length > 0) definition.tools = tools;\n const sandbox = resolveSandbox(fields, filename);\n if (sandbox !== undefined) definition.sandbox = sandbox;\n\n const name = asString(fields.name) ?? filename.replace(/\\.md$/, \"\");\n return { name, definition };\n}\n\nfunction rejectUnknownFields(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): void {\n for (const key of Object.keys(fields)) {\n if (!ACCEPTED_FIELDS.has(key)) {\n throw new ConfigurationError(\n `Subagent ${filename}: unknown frontmatter field \"${key}\" (accepted: ${[...ACCEPTED_FIELDS].join(\", \")})`,\n { code: \"subagent_unknown_field\" },\n );\n }\n }\n}\n\n// mcp: a known field, but not yet honored on the LOCAL delegation path. The frontmatter YAML can only\n// express server NAMES (parseSimpleYaml has no nested-object support), while a child's `Agent.create`\n// needs `mcpServers` as a Record<name, config>; resolving names→config per-subagent in local delegation\n// is its own follow-up. Rather than silently drop it (the M26/M32 silent-gate class), it is a typed load\n// error that names the field and points at the alternative.\nfunction rejectMcp(fields: Record<string, FrontmatterValue | undefined>, filename: string): void {\n if (fields.mcp !== undefined) {\n throw new ConfigurationError(\n `Subagent ${filename}: per-subagent \"mcp\" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,\n { code: \"subagent_mcp_unsupported_local\" },\n );\n }\n}\n\n// model + reasoning_effort — effort rides inside `model.params[thinking]`, so it requires a concrete\n// model id to attach to (a child inheriting the parent's model cannot carry the parent's provider-\n// specific effort param safely).\nfunction resolveModel(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): ModelSelection | \"inherit\" | undefined {\n const modelId = asString(fields.model);\n const effort = asString(fields.reasoning_effort);\n // reasoning_effort rides in model.params[thinking], so it needs a CONCRETE model id to attach to.\n // Neither an absent model NOR `model: inherit` can carry it (the inherited id is unknown at load), so\n // both are typed errors rather than a silently-dropped effort — the silent-gate class this guards.\n if (effort !== undefined && (modelId === undefined || modelId === \"inherit\")) {\n throw new ConfigurationError(\n `Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or \"inherit\" cannot carry it)`,\n { code: \"subagent_reasoning_effort_without_model\" },\n );\n }\n if (modelId === undefined) return undefined;\n if (modelId === \"inherit\") return \"inherit\";\n return effort !== undefined\n ? { id: modelId, params: [{ id: \"thinking\", value: effort }] }\n : { id: modelId };\n}\n\n// sandbox: boolean only. A granular mode string (read-only/…) is unsupported by the SDK runtime and is\n// a typed error rather than a silent coercion to a boolean.\nfunction resolveSandbox(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): boolean | undefined {\n if (fields.sandbox === undefined) return undefined;\n if (typeof fields.sandbox !== \"boolean\") {\n throw new ConfigurationError(\n `Subagent ${filename}: sandbox must be a boolean (got \"${String(fields.sandbox)}\"); granular sandbox modes are not supported by the runtime`,\n { code: \"subagent_sandbox_not_boolean\" },\n );\n }\n return fields.sandbox;\n}\n\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n if (typeof v !== \"string\") return undefined;\n // parseSimpleYaml does not strip quotes (documented), and `model`/`reasoning_effort` are fields users\n // habitually quote (`model: \"openai/gpt-4o\"`). Strip a single matching surrounding quote pair so a\n // quoted id/effort does not slip past validation and fail only at the provider.\n const m = /^([\"'])(.*)\\1$/.exec(v);\n return m ? m[2] : v;\n}\n\n/** Accept a YAML list (`string[]`) or a comma/space-separated scalar; trim + drop empties. */\nfunction toStringList(v: FrontmatterValue | undefined): string[] {\n if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);\n if (typeof v === \"string\") {\n return v\n .split(/[\\s,]+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0);\n }\n return [];\n}\n\nfunction splitFrontmatter(raw: string, filename: string): { frontmatter: string; body: string } {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Subagent ${filename} is missing frontmatter`, {\n code: \"subagent_missing_frontmatter\",\n });\n }\n return { frontmatter: match[1] ?? \"\", body: (match[2] ?? \"\").trim() };\n}\n\nfunction parseFrontmatterFields(frontmatter: string): Record<string, FrontmatterValue | undefined> {\n // Preserve the rich YAML value types (boolean/number/string[]): `sandbox: true` and\n // `mcp: [a, b]` are meaningful here, so narrowing everything to string (as the\n // pre-M33 loader did) would drop them. Per-field validation happens in parseSubagentMarkdown.\n return parseSimpleYaml(frontmatter);\n}\n"]}
|