agentloom 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -2
- package/dist/core/codex.d.ts +3 -0
- package/dist/core/codex.js +72 -0
- package/dist/core/migration.js +2 -27
- package/dist/sync/index.js +7 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -202,13 +202,24 @@ claude:
|
|
|
202
202
|
model: sonnet
|
|
203
203
|
codex:
|
|
204
204
|
model: gpt-5-codex
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
model_reasoning_effort: medium
|
|
206
|
+
web_search: true
|
|
207
207
|
---
|
|
208
208
|
|
|
209
209
|
You are a strict reviewer...
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
+
For Codex, provider-native config keys are passed through to the generated
|
|
213
|
+
`.codex/agents/<role>.toml` as a thin layer. Prefer Codex's native snake_case
|
|
214
|
+
keys such as `approval_policy`, `approvals_reviewer`, or `web_search`. Existing
|
|
215
|
+
camelCase aliases like `reasoningEffort` are still normalized for
|
|
216
|
+
backward-compatibility.
|
|
217
|
+
|
|
218
|
+
Current `codex-cli 0.121.0` exposes spawn-time controls such as `fork_context` and
|
|
219
|
+
`fork_turns` only on the `spawn_agent` tool path, not in static role/config
|
|
220
|
+
files, so Codex itself will warn or ignore them if you place them under
|
|
221
|
+
`codex:` in canonical frontmatter today.
|
|
222
|
+
|
|
212
223
|
## Command schema
|
|
213
224
|
|
|
214
225
|
Canonical commands are markdown files. Frontmatter is optional. When present,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function normalizeCodexConfigForToml(providerConfig: Record<string, unknown>): Record<string, unknown>;
|
|
2
|
+
export declare function cloneCodexProviderConfig(providerConfig: Record<string, unknown>): Record<string, unknown>;
|
|
3
|
+
export declare function stripManagedCodexInstructionKeys(providerConfig: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isObject } from "./fs.js";
|
|
2
|
+
const MANAGED_INSTRUCTION_KEYS = new Set([
|
|
3
|
+
"developerInstructions",
|
|
4
|
+
"developer_instructions",
|
|
5
|
+
"modelInstructionsFile",
|
|
6
|
+
"model_instructions_file",
|
|
7
|
+
]);
|
|
8
|
+
const LEGACY_CODEX_ALIASES = {
|
|
9
|
+
approvalPolicy: "approval_policy",
|
|
10
|
+
reasoningEffort: "model_reasoning_effort",
|
|
11
|
+
reasoningSummary: "model_reasoning_summary",
|
|
12
|
+
sandboxMode: "sandbox_mode",
|
|
13
|
+
verbosity: "model_verbosity",
|
|
14
|
+
webSearch: "web_search",
|
|
15
|
+
};
|
|
16
|
+
export function normalizeCodexConfigForToml(providerConfig) {
|
|
17
|
+
const normalized = normalizeCodexValueForToml(providerConfig);
|
|
18
|
+
if (!isObject(normalized)) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
for (const key of MANAGED_INSTRUCTION_KEYS) {
|
|
22
|
+
delete normalized[key];
|
|
23
|
+
}
|
|
24
|
+
return normalized;
|
|
25
|
+
}
|
|
26
|
+
export function cloneCodexProviderConfig(providerConfig) {
|
|
27
|
+
const cloned = cloneCodexValue(providerConfig);
|
|
28
|
+
if (!isObject(cloned)) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
return cloned;
|
|
32
|
+
}
|
|
33
|
+
export function stripManagedCodexInstructionKeys(providerConfig) {
|
|
34
|
+
const cleaned = cloneCodexProviderConfig(providerConfig);
|
|
35
|
+
for (const key of MANAGED_INSTRUCTION_KEYS) {
|
|
36
|
+
delete cleaned[key];
|
|
37
|
+
}
|
|
38
|
+
return cleaned;
|
|
39
|
+
}
|
|
40
|
+
function normalizeCodexValueForToml(value) {
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
return value.map((entry) => normalizeCodexValueForToml(entry));
|
|
43
|
+
}
|
|
44
|
+
if (!isObject(value)) {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
48
|
+
toSnakeCase(key),
|
|
49
|
+
normalizeCodexValueForToml(entry),
|
|
50
|
+
]));
|
|
51
|
+
}
|
|
52
|
+
function cloneCodexValue(value) {
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
return value.map((entry) => cloneCodexValue(entry));
|
|
55
|
+
}
|
|
56
|
+
if (!isObject(value)) {
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, cloneCodexValue(entry)]));
|
|
60
|
+
}
|
|
61
|
+
function toSnakeCase(key) {
|
|
62
|
+
if (Object.prototype.hasOwnProperty.call(LEGACY_CODEX_ALIASES, key)) {
|
|
63
|
+
return LEGACY_CODEX_ALIASES[key];
|
|
64
|
+
}
|
|
65
|
+
if (!/[A-Z]/.test(key)) {
|
|
66
|
+
return key;
|
|
67
|
+
}
|
|
68
|
+
return key
|
|
69
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2")
|
|
70
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1_$2")
|
|
71
|
+
.toLowerCase();
|
|
72
|
+
}
|
package/dist/core/migration.js
CHANGED
|
@@ -6,6 +6,7 @@ import TOML from "@iarna/toml";
|
|
|
6
6
|
import matter from "gray-matter";
|
|
7
7
|
import YAML from "yaml";
|
|
8
8
|
import { buildAgentMarkdown, parseAgentsDir } from "./agents.js";
|
|
9
|
+
import { cloneCodexProviderConfig, stripManagedCodexInstructionKeys, } from "./codex.js";
|
|
9
10
|
import { normalizeCommandArgumentsForCanonical, parseCommandsDir, } from "./commands.js";
|
|
10
11
|
import { ensureDir, isObject, readJsonIfExists, slugify } from "./fs.js";
|
|
11
12
|
import { readLockfile, writeLockfile } from "./lockfile.js";
|
|
@@ -394,33 +395,7 @@ function readCodexProviderAgents(paths) {
|
|
|
394
395
|
const description = isObject(roleEntry) && typeof roleEntry.description === "string"
|
|
395
396
|
? roleEntry.description.trim()
|
|
396
397
|
: roleName;
|
|
397
|
-
const providerConfig =
|
|
398
|
-
if (typeof roleToml.model === "string") {
|
|
399
|
-
providerConfig.model = roleToml.model;
|
|
400
|
-
}
|
|
401
|
-
if (typeof roleToml.model_reasoning_effort === "string") {
|
|
402
|
-
providerConfig.reasoningEffort = roleToml.model_reasoning_effort;
|
|
403
|
-
}
|
|
404
|
-
if (typeof roleToml.model_reasoning_summary === "string") {
|
|
405
|
-
providerConfig.reasoningSummary = roleToml.model_reasoning_summary;
|
|
406
|
-
}
|
|
407
|
-
if (typeof roleToml.model_verbosity === "string") {
|
|
408
|
-
providerConfig.verbosity = roleToml.model_verbosity;
|
|
409
|
-
}
|
|
410
|
-
if (typeof roleToml.approval_policy === "string") {
|
|
411
|
-
providerConfig.approvalPolicy = roleToml.approval_policy;
|
|
412
|
-
}
|
|
413
|
-
if (typeof roleToml.sandbox_mode === "string") {
|
|
414
|
-
providerConfig.sandboxMode = roleToml.sandbox_mode;
|
|
415
|
-
}
|
|
416
|
-
if (typeof roleToml.web_search === "boolean") {
|
|
417
|
-
providerConfig.webSearch = roleToml.web_search;
|
|
418
|
-
}
|
|
419
|
-
if (typeof providerConfig.webSearch !== "boolean" &&
|
|
420
|
-
isObject(roleToml.tools) &&
|
|
421
|
-
typeof roleToml.tools.web_search === "boolean") {
|
|
422
|
-
providerConfig.webSearch = roleToml.tools.web_search;
|
|
423
|
-
}
|
|
398
|
+
const providerConfig = stripManagedCodexInstructionKeys(cloneCodexProviderConfig(roleToml));
|
|
424
399
|
records.push({
|
|
425
400
|
provider: "codex",
|
|
426
401
|
sourcePath: roleTomlPath,
|
package/dist/sync/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import YAML from "yaml";
|
|
|
6
6
|
import { ALL_PROVIDERS } from "../types.js";
|
|
7
7
|
import { getProviderConfig, isProviderEnabled, parseAgentsDir, } from "../core/agents.js";
|
|
8
8
|
import { parseCommandsDir, renderCommandForProvider, } from "../core/commands.js";
|
|
9
|
+
import { normalizeCodexConfigForToml } from "../core/codex.js";
|
|
9
10
|
import { parseRulesDir, renderRuleForCursor, upsertManagedRuleBlocks, } from "../core/rules.js";
|
|
10
11
|
import { ensureDir, isObject, readJsonIfExists, readTextIfExists, relativePosix, removeFileIfExists, slugify, toPosixPath, writeJsonAtomic, writeTextAtomic, } from "../core/fs.js";
|
|
11
12
|
import { readManifest, writeManifest } from "../core/manifest.js";
|
|
@@ -869,33 +870,15 @@ function resolveCodexDeveloperInstructions(agentBody, providerConfig) {
|
|
|
869
870
|
providerConfig.developerInstructions.trim() !== "") {
|
|
870
871
|
return providerConfig.developerInstructions.trim();
|
|
871
872
|
}
|
|
873
|
+
if (typeof providerConfig.developer_instructions === "string" &&
|
|
874
|
+
providerConfig.developer_instructions.trim() !== "") {
|
|
875
|
+
return providerConfig.developer_instructions.trim();
|
|
876
|
+
}
|
|
872
877
|
return agentBody.trimStart().trimEnd();
|
|
873
878
|
}
|
|
874
879
|
function buildCodexRoleToml(developerInstructions, providerConfig) {
|
|
875
|
-
const roleToml =
|
|
876
|
-
|
|
877
|
-
};
|
|
878
|
-
if (typeof providerConfig.model === "string") {
|
|
879
|
-
roleToml.model = providerConfig.model;
|
|
880
|
-
}
|
|
881
|
-
if (typeof providerConfig.reasoningEffort === "string") {
|
|
882
|
-
roleToml.model_reasoning_effort = providerConfig.reasoningEffort;
|
|
883
|
-
}
|
|
884
|
-
if (typeof providerConfig.reasoningSummary === "string") {
|
|
885
|
-
roleToml.model_reasoning_summary = providerConfig.reasoningSummary;
|
|
886
|
-
}
|
|
887
|
-
if (typeof providerConfig.verbosity === "string") {
|
|
888
|
-
roleToml.model_verbosity = providerConfig.verbosity;
|
|
889
|
-
}
|
|
890
|
-
if (typeof providerConfig.approvalPolicy === "string") {
|
|
891
|
-
roleToml.approval_policy = providerConfig.approvalPolicy;
|
|
892
|
-
}
|
|
893
|
-
if (typeof providerConfig.sandboxMode === "string") {
|
|
894
|
-
roleToml.sandbox_mode = providerConfig.sandboxMode;
|
|
895
|
-
}
|
|
896
|
-
if (typeof providerConfig.webSearch === "boolean") {
|
|
897
|
-
roleToml.web_search = providerConfig.webSearch;
|
|
898
|
-
}
|
|
880
|
+
const roleToml = normalizeCodexConfigForToml(providerConfig);
|
|
881
|
+
roleToml.developer_instructions = developerInstructions;
|
|
899
882
|
return roleToml;
|
|
900
883
|
}
|
|
901
884
|
function mapMcpServers(servers, allowedKeys) {
|