@pi-ohm/config 0.6.3 → 0.6.4-dev.22132458683.1.8646f56
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 +8 -0
- package/package.json +1 -1
- package/src/index.ts +113 -0
package/README.md
CHANGED
|
@@ -11,3 +11,11 @@ Responsibilities:
|
|
|
11
11
|
- `${configDir}/ohm.json`
|
|
12
12
|
- `${configDir}/ohm.providers.json`
|
|
13
13
|
- expose typed runtime config helpers to feature packages
|
|
14
|
+
|
|
15
|
+
Subagents runtime config highlights:
|
|
16
|
+
|
|
17
|
+
- `subagents.taskMaxConcurrency`
|
|
18
|
+
- `subagents.taskRetentionMs`
|
|
19
|
+
- `subagents.permissions.default` (`allow|deny`)
|
|
20
|
+
- `subagents.permissions.subagents` (per-subagent overrides)
|
|
21
|
+
- `subagents.permissions.allowInternalRouting`
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -38,11 +38,22 @@ export interface OhmPainterProviders {
|
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export interface OhmSubagentRuntimeConfig {
|
|
42
|
+
taskMaxConcurrency: number;
|
|
43
|
+
taskRetentionMs: number;
|
|
44
|
+
permissions: {
|
|
45
|
+
default: "allow" | "deny";
|
|
46
|
+
subagents: Record<string, "allow" | "deny">;
|
|
47
|
+
allowInternalRouting: boolean;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
export interface OhmRuntimeConfig {
|
|
42
52
|
defaultMode: OhmMode;
|
|
43
53
|
subagentBackend: OhmSubagentBackend;
|
|
44
54
|
features: OhmFeatureFlags;
|
|
45
55
|
painter: OhmPainterProviders;
|
|
56
|
+
subagents?: OhmSubagentRuntimeConfig;
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
export interface OhmConfigPaths {
|
|
@@ -84,6 +95,15 @@ const DEFAULT_OHM_CONFIG: OhmRuntimeConfig = {
|
|
|
84
95
|
apiVersion: "2025-04-01-preview",
|
|
85
96
|
},
|
|
86
97
|
},
|
|
98
|
+
subagents: {
|
|
99
|
+
taskMaxConcurrency: 3,
|
|
100
|
+
taskRetentionMs: 1000 * 60 * 60 * 24,
|
|
101
|
+
permissions: {
|
|
102
|
+
default: "allow",
|
|
103
|
+
subagents: {},
|
|
104
|
+
allowInternalRouting: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
87
107
|
};
|
|
88
108
|
|
|
89
109
|
type JsonMap = Record<string, unknown>;
|
|
@@ -156,6 +176,41 @@ function normalizeString(value: unknown, fallback: string): string {
|
|
|
156
176
|
return fallback;
|
|
157
177
|
}
|
|
158
178
|
|
|
179
|
+
function normalizePositiveInteger(value: unknown, fallback: number): number {
|
|
180
|
+
if (typeof value !== "number") return fallback;
|
|
181
|
+
if (!Number.isInteger(value) || value <= 0) return fallback;
|
|
182
|
+
return value;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function normalizePermissionDecision(value: unknown, fallback: "allow" | "deny"): "allow" | "deny" {
|
|
186
|
+
if (value === "allow" || value === "deny") return value;
|
|
187
|
+
|
|
188
|
+
// Legacy compatibility: treat deprecated "ask" as deny-safe behavior.
|
|
189
|
+
if (value === "ask") return "deny";
|
|
190
|
+
|
|
191
|
+
return fallback;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function normalizePermissionDecisionMap(
|
|
195
|
+
value: unknown,
|
|
196
|
+
fallback: Record<string, "allow" | "deny">,
|
|
197
|
+
): Record<string, "allow" | "deny"> {
|
|
198
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
199
|
+
return fallback;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const normalized: Record<string, "allow" | "deny"> = {};
|
|
203
|
+
for (const [key, decision] of Object.entries(value)) {
|
|
204
|
+
const trimmedKey = key.trim().toLowerCase();
|
|
205
|
+
if (trimmedKey.length === 0) continue;
|
|
206
|
+
|
|
207
|
+
const normalizedDecision = normalizePermissionDecision(decision, "allow");
|
|
208
|
+
normalized[trimmedKey] = normalizedDecision;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return normalized;
|
|
212
|
+
}
|
|
213
|
+
|
|
159
214
|
function mergeConfig(base: OhmRuntimeConfig, patch: JsonMap): OhmRuntimeConfig {
|
|
160
215
|
const next: OhmRuntimeConfig = structuredClone(base);
|
|
161
216
|
|
|
@@ -232,6 +287,64 @@ function mergeConfig(base: OhmRuntimeConfig, patch: JsonMap): OhmRuntimeConfig {
|
|
|
232
287
|
next.painter.azureOpenai.apiVersion,
|
|
233
288
|
);
|
|
234
289
|
|
|
290
|
+
const subagentPatch =
|
|
291
|
+
patch.subagents && typeof patch.subagents === "object"
|
|
292
|
+
? (patch.subagents as JsonMap)
|
|
293
|
+
: undefined;
|
|
294
|
+
|
|
295
|
+
const subagentDefaults =
|
|
296
|
+
next.subagents ??
|
|
297
|
+
({
|
|
298
|
+
taskMaxConcurrency: DEFAULT_OHM_CONFIG.subagents?.taskMaxConcurrency ?? 3,
|
|
299
|
+
taskRetentionMs: DEFAULT_OHM_CONFIG.subagents?.taskRetentionMs ?? 1000 * 60 * 60 * 24,
|
|
300
|
+
permissions: {
|
|
301
|
+
default: DEFAULT_OHM_CONFIG.subagents?.permissions.default ?? "allow",
|
|
302
|
+
subagents: DEFAULT_OHM_CONFIG.subagents?.permissions.subagents ?? {},
|
|
303
|
+
allowInternalRouting:
|
|
304
|
+
DEFAULT_OHM_CONFIG.subagents?.permissions.allowInternalRouting ?? false,
|
|
305
|
+
},
|
|
306
|
+
} satisfies OhmSubagentRuntimeConfig);
|
|
307
|
+
|
|
308
|
+
const taskMaxConcurrency = normalizePositiveInteger(
|
|
309
|
+
subagentPatch?.taskMaxConcurrency,
|
|
310
|
+
subagentDefaults.taskMaxConcurrency,
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
const taskRetentionMs = normalizePositiveInteger(
|
|
314
|
+
subagentPatch?.taskRetentionMs,
|
|
315
|
+
subagentDefaults.taskRetentionMs,
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
const permissionsPatch =
|
|
319
|
+
subagentPatch?.permissions && typeof subagentPatch.permissions === "object"
|
|
320
|
+
? (subagentPatch.permissions as JsonMap)
|
|
321
|
+
: undefined;
|
|
322
|
+
|
|
323
|
+
const permissionsDefault = normalizePermissionDecision(
|
|
324
|
+
permissionsPatch?.default,
|
|
325
|
+
subagentDefaults.permissions.default,
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
const permissionsSubagents = normalizePermissionDecisionMap(
|
|
329
|
+
permissionsPatch?.subagents,
|
|
330
|
+
subagentDefaults.permissions.subagents,
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
const allowInternalRouting = normalizeBoolean(
|
|
334
|
+
permissionsPatch?.allowInternalRouting,
|
|
335
|
+
subagentDefaults.permissions.allowInternalRouting,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
next.subagents = {
|
|
339
|
+
taskMaxConcurrency,
|
|
340
|
+
taskRetentionMs,
|
|
341
|
+
permissions: {
|
|
342
|
+
default: permissionsDefault,
|
|
343
|
+
subagents: permissionsSubagents,
|
|
344
|
+
allowInternalRouting,
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
|
|
235
348
|
return next;
|
|
236
349
|
}
|
|
237
350
|
|