@agenr/openclaw-plugin 3.3.0 → 2026.6.2

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.
@@ -0,0 +1,1750 @@
1
+ import {
2
+ describeClaimKeyNormalizationFailure,
3
+ normalizeClaimKey,
4
+ normalizeClaimKeySegment
5
+ } from "./chunk-VBPYU7GO.js";
6
+
7
+ // src/filesystem-path.ts
8
+ import path from "path";
9
+ import { fileURLToPath, pathToFileURL } from "url";
10
+ function toAbsoluteFileUrl(filePath) {
11
+ return pathToFileURL(path.resolve(filePath)).href;
12
+ }
13
+ function resolveLocalFilesystemPath(targetPath) {
14
+ const trimmedPath = targetPath.trim();
15
+ if (trimmedPath.length === 0 || trimmedPath === ":memory:" || isInMemoryFileUrl(trimmedPath)) {
16
+ return null;
17
+ }
18
+ if (trimmedPath.startsWith("file:")) {
19
+ if (isAbsoluteFileUrl(trimmedPath)) {
20
+ try {
21
+ return fileURLToPath(trimmedPath);
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+ const relativePath = decodeRelativeFileUrlPath(trimmedPath);
27
+ return relativePath ? path.resolve(relativePath) : null;
28
+ }
29
+ return path.resolve(trimmedPath);
30
+ }
31
+ function resolveConfigFilesystemPath(targetPath) {
32
+ return resolveLocalFilesystemPath(targetPath) ?? targetPath;
33
+ }
34
+ function isAbsoluteFileUrl(targetPath) {
35
+ return /^file:(?:\/|[A-Za-z]:[\\/])/u.test(targetPath);
36
+ }
37
+ function isInMemoryFileUrl(targetPath) {
38
+ return targetPath === "file::memory:" || targetPath.startsWith("file::memory:?");
39
+ }
40
+ function decodeRelativeFileUrlPath(targetPath) {
41
+ const rawPath = targetPath.slice("file:".length).split(/[?#]/u, 1)[0]?.trim();
42
+ if (!rawPath) {
43
+ return null;
44
+ }
45
+ try {
46
+ return decodeURIComponent(rawPath);
47
+ } catch {
48
+ return rawPath;
49
+ }
50
+ }
51
+
52
+ // src/core/types.ts
53
+ var DURABLE_KINDS = ["fact", "decision", "preference", "lesson", "relationship", "milestone", "directive"];
54
+ var DIRECTIVE_POLARITIES = ["abstain", "proactive"];
55
+ var DIRECTIVE_BASE_TRIGGERS = ["session_start", "always"];
56
+ var EXPIRY_LEVELS = ["core", "permanent", "temporary"];
57
+ var CLAIM_KEY_STATUSES = ["trusted", "tentative", "unresolved"];
58
+ var CLAIM_KEY_SOURCES = [
59
+ "manual",
60
+ "model",
61
+ "json_retry",
62
+ "deterministic_repair",
63
+ "dreaming_extract",
64
+ "dreaming_reconcile",
65
+ "dreaming_temporalize",
66
+ "dreaming_project"
67
+ ];
68
+ var CLAIM_SUPPORT_MODES = ["explicit", "normalized", "inferred"];
69
+ var EPISODE_ACTIVITY_LEVELS = ["substantial", "minimal", "none"];
70
+ var PROCEDURE_STEP_KINDS = ["run_command", "read_reference", "inspect_state", "edit_file", "ask_user", "invoke_tool", "verify"];
71
+ var PROCEDURE_CONDITION_KINDS = ["harness_is", "tool_available", "file_exists", "path_exists", "env_flag", "repo_state", "user_confirmed"];
72
+ var PROCEDURE_SOURCE_KINDS = ["skill", "doc", "durable", "episode", "repo_file", "manual"];
73
+
74
+ // src/app/features/types.ts
75
+ var AGENR_FEATURE_FLAG_KEYS = ["workingMemory", "sessionTreeLineage", "sessionTreeCompaction", "goalContinuation"];
76
+ var DEFAULT_AGENR_FEATURE_FLAGS = {
77
+ workingMemory: false,
78
+ sessionTreeLineage: false,
79
+ sessionTreeCompaction: true,
80
+ goalContinuation: false
81
+ };
82
+ function createAllEnabledFeatureFlagConfig() {
83
+ return Object.fromEntries(AGENR_FEATURE_FLAG_KEYS.map((key) => [key, true]));
84
+ }
85
+
86
+ // src/adapters/config/types.ts
87
+ var DEFAULT_DREAMING_DAILY_COST_CAP = 75;
88
+ var DEFAULT_DREAMING_PRUNE_PROTECT_RECALLED_DAYS = 14;
89
+ var DEFAULT_DREAMING_PRUNE_PROTECT_MIN_IMPORTANCE = 9;
90
+ var DEFAULT_DREAMING_IMPORTANCE_THRESHOLD = 25;
91
+ var DEFAULT_DREAMING_MIN_INTERVAL_MINUTES = 30;
92
+ var DEFAULT_DREAMING_EXTRACT_MAX_SESSIONS = 8;
93
+ var DEFAULT_DREAMING_LIGHT_MAX_SESSIONS = 2;
94
+ var DEFAULT_DREAMING_MAX_PROFILE_DURABLES = 8;
95
+ var DEFAULT_DREAMING_DEEP_INTERVAL_HOURS = 168;
96
+ var DEFAULT_CLAIM_EXTRACTION_CONCURRENCY = 10;
97
+ var DEFAULT_CLAIM_EXTRACTION_CONFIDENCE_THRESHOLD = 0.8;
98
+ var DEFAULT_CLAIM_EXTRACTION_ELIGIBLE_TYPES = ["fact", "preference", "decision", "lesson"];
99
+ var DEFAULT_API_PORT = 3e3;
100
+ var AUTH_METHOD_DEFINITIONS = [
101
+ {
102
+ id: "openai-api-key",
103
+ provider: "openai",
104
+ title: "OpenAI API key",
105
+ setupDescription: "Standard OpenAI API key. Pay per token.",
106
+ preferredModels: ["gpt-5.4-mini", "gpt-5.4", "gpt-5.4-nano"]
107
+ },
108
+ {
109
+ id: "openai-subscription",
110
+ provider: "openai-codex",
111
+ title: "OpenAI - Subscription (via Codex CLI)",
112
+ setupDescription: "Uses your Codex CLI login. No per-token cost. Requires `codex auth`.",
113
+ preferredModels: ["gpt-5.4-mini", "gpt-5.4"]
114
+ },
115
+ {
116
+ id: "anthropic-api-key",
117
+ provider: "anthropic",
118
+ title: "Anthropic API key",
119
+ setupDescription: "Standard Anthropic API key. Pay per token.",
120
+ preferredModels: ["claude-sonnet-4-6", "claude-opus-4-6", "claude-haiku-4-5"]
121
+ },
122
+ {
123
+ id: "anthropic-oauth",
124
+ provider: "anthropic",
125
+ title: "Anthropic - Claude subscription (OAuth)",
126
+ setupDescription: "Uses your Claude Code CLI login. No per-token cost.",
127
+ preferredModels: ["claude-sonnet-4-6", "claude-opus-4-6", "claude-haiku-4-5"]
128
+ },
129
+ {
130
+ id: "anthropic-token",
131
+ provider: "anthropic",
132
+ title: "Anthropic - Claude subscription (long-lived token)",
133
+ setupDescription: "Uses a Claude long-lived token instead of an API key.",
134
+ preferredModels: ["claude-sonnet-4-6", "claude-opus-4-6", "claude-haiku-4-5"]
135
+ }
136
+ ];
137
+ var AUTH_METHOD_SET = new Set(AUTH_METHOD_DEFINITIONS.map((definition) => definition.id));
138
+ var SUPPORTED_AGENR_PROVIDERS = ["openai", "openai-codex", "anthropic"];
139
+ function isAgenrAuthMethod(value) {
140
+ return AUTH_METHOD_SET.has(value);
141
+ }
142
+ function isAgenrProvider(value) {
143
+ return SUPPORTED_AGENR_PROVIDERS.includes(value);
144
+ }
145
+ function authMethodToProvider(auth) {
146
+ const definition = AUTH_METHOD_DEFINITIONS.find((candidate) => candidate.id === auth);
147
+ if (!definition) {
148
+ throw new Error(`Unsupported auth method "${auth}".`);
149
+ }
150
+ return definition.provider;
151
+ }
152
+ function getAuthMethodDefinition(auth) {
153
+ const definition = AUTH_METHOD_DEFINITIONS.find((candidate) => candidate.id === auth);
154
+ if (!definition) {
155
+ throw new Error(`Unsupported auth method "${auth}".`);
156
+ }
157
+ return definition;
158
+ }
159
+ function sameEligibleKinds(left, right) {
160
+ return left.length === right.length && left.every((value, index) => value === right[index]);
161
+ }
162
+ function isDurableKind(value) {
163
+ return DURABLE_KINDS.includes(value);
164
+ }
165
+
166
+ // src/config.ts
167
+ import fs from "fs";
168
+ import os from "os";
169
+ import path2 from "path";
170
+
171
+ // src/adapters/shared/validation.ts
172
+ function isRecord(value) {
173
+ return typeof value === "object" && value !== null && !Array.isArray(value);
174
+ }
175
+ function readOptionalTrimmedString(value) {
176
+ if (typeof value !== "string") {
177
+ return void 0;
178
+ }
179
+ const trimmed = value.trim();
180
+ return trimmed || void 0;
181
+ }
182
+ function readOptionalFiniteNumber(value) {
183
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
184
+ }
185
+ function pushIssue(issues, path3, message) {
186
+ issues.push({ path: path3, message });
187
+ }
188
+ function pushUnexpectedFields(value, allowedKeys, basePath, issues) {
189
+ for (const key of Object.keys(value)) {
190
+ if (allowedKeys.has(key)) {
191
+ continue;
192
+ }
193
+ pushIssue(issues, joinPath(basePath, key), "Unexpected field.");
194
+ }
195
+ }
196
+ function parseRequiredTrimmedString(value, path3, issues, message = "Expected a non-empty string.") {
197
+ if (typeof value !== "string") {
198
+ pushIssue(issues, path3, message);
199
+ return void 0;
200
+ }
201
+ const normalized = value.trim();
202
+ if (normalized.length === 0) {
203
+ pushIssue(issues, path3, message);
204
+ return void 0;
205
+ }
206
+ return normalized;
207
+ }
208
+ function parseOptionalTrimmedString(value, path3, issues, typeMessage = "Expected a string.", emptyMessage = "Expected a non-empty string.") {
209
+ if (value === void 0) {
210
+ return void 0;
211
+ }
212
+ if (typeof value !== "string") {
213
+ pushIssue(issues, path3, typeMessage);
214
+ return void 0;
215
+ }
216
+ const normalized = value.trim();
217
+ if (normalized.length === 0) {
218
+ pushIssue(issues, path3, emptyMessage);
219
+ return void 0;
220
+ }
221
+ return normalized;
222
+ }
223
+ function parseOptionalBoolean(value, path3, issues, message = "Expected a boolean.") {
224
+ if (value === void 0) {
225
+ return void 0;
226
+ }
227
+ if (typeof value !== "boolean") {
228
+ pushIssue(issues, path3, message);
229
+ return void 0;
230
+ }
231
+ return value;
232
+ }
233
+ function parseOptionalIntegerInRange(value, path3, issues, bounds) {
234
+ if (value === void 0) {
235
+ return void 0;
236
+ }
237
+ if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
238
+ pushIssue(issues, path3, integerRangeMessage(bounds));
239
+ return void 0;
240
+ }
241
+ if (bounds.min !== void 0 && value < bounds.min) {
242
+ pushIssue(issues, path3, integerRangeMessage(bounds));
243
+ return void 0;
244
+ }
245
+ if (bounds.max !== void 0 && value > bounds.max) {
246
+ pushIssue(issues, path3, integerRangeMessage(bounds));
247
+ return void 0;
248
+ }
249
+ return value;
250
+ }
251
+ function parseOptionalTimestampString(value, path3, issues, message = "Expected a valid timestamp string.") {
252
+ const timestamp = parseOptionalTrimmedString(value, path3, issues);
253
+ if (timestamp === void 0) {
254
+ return void 0;
255
+ }
256
+ if (Number.isNaN(Date.parse(timestamp))) {
257
+ pushIssue(issues, path3, message);
258
+ return void 0;
259
+ }
260
+ return timestamp;
261
+ }
262
+ function joinPath(basePath, key) {
263
+ return basePath.length > 0 ? `${basePath}.${key}` : key;
264
+ }
265
+ function integerRangeMessage(bounds) {
266
+ if (bounds.message) {
267
+ return bounds.message;
268
+ }
269
+ if (bounds.min === 0 && bounds.max === void 0) {
270
+ return "Expected a non-negative integer.";
271
+ }
272
+ if (bounds.min === 1 && bounds.max === void 0) {
273
+ return "Expected a positive integer.";
274
+ }
275
+ if (bounds.min !== void 0 && bounds.max !== void 0) {
276
+ return `Expected an integer from ${bounds.min} to ${bounds.max}.`;
277
+ }
278
+ if (bounds.min !== void 0) {
279
+ return `Expected an integer greater than or equal to ${bounds.min}.`;
280
+ }
281
+ if (bounds.max !== void 0) {
282
+ return `Expected an integer less than or equal to ${bounds.max}.`;
283
+ }
284
+ return "Expected an integer.";
285
+ }
286
+
287
+ // src/adapters/config/parse-feature-flags.ts
288
+ function parseFeatureFlags(value, path3, issues) {
289
+ const defaults = DEFAULT_AGENR_FEATURE_FLAGS;
290
+ if (value === void 0) {
291
+ return {
292
+ resolved: { ...defaults }
293
+ };
294
+ }
295
+ if (!isRecord(value)) {
296
+ pushIssue(issues, path3, "Expected an object.");
297
+ return {
298
+ resolved: { ...defaults }
299
+ };
300
+ }
301
+ const startIndex = issues.length;
302
+ pushUnexpectedFields(value, new Set(AGENR_FEATURE_FLAG_KEYS), path3, issues);
303
+ const workingMemory = parseOptionalBoolean(value.workingMemory, `${path3}.workingMemory`, issues);
304
+ const sessionTreeLineage = parseOptionalBoolean(value.sessionTreeLineage, `${path3}.sessionTreeLineage`, issues);
305
+ const sessionTreeCompaction = parseOptionalBoolean(value.sessionTreeCompaction, `${path3}.sessionTreeCompaction`, issues);
306
+ const goalContinuation = parseOptionalBoolean(value.goalContinuation, `${path3}.goalContinuation`, issues);
307
+ if (issues.length > startIndex) {
308
+ return {
309
+ resolved: { ...defaults }
310
+ };
311
+ }
312
+ const input = {
313
+ ...workingMemory === true ? { workingMemory } : {},
314
+ ...sessionTreeLineage === true ? { sessionTreeLineage } : {},
315
+ ...sessionTreeCompaction === false ? { sessionTreeCompaction: false } : {},
316
+ ...goalContinuation === true ? { goalContinuation } : {}
317
+ };
318
+ return {
319
+ ...Object.keys(input).length > 0 ? { input } : {},
320
+ resolved: {
321
+ workingMemory: workingMemory ?? defaults.workingMemory,
322
+ sessionTreeLineage: sessionTreeLineage ?? defaults.sessionTreeLineage,
323
+ sessionTreeCompaction: sessionTreeCompaction ?? defaults.sessionTreeCompaction,
324
+ goalContinuation: goalContinuation ?? defaults.goalContinuation
325
+ }
326
+ };
327
+ }
328
+ function toFeatureFlagInput(value) {
329
+ if (!value) {
330
+ return void 0;
331
+ }
332
+ const defaults = DEFAULT_AGENR_FEATURE_FLAGS;
333
+ const input = {
334
+ ...value.workingMemory !== defaults.workingMemory ? { workingMemory: value.workingMemory } : {},
335
+ ...value.sessionTreeLineage !== defaults.sessionTreeLineage ? { sessionTreeLineage: value.sessionTreeLineage } : {},
336
+ ...value.sessionTreeCompaction !== defaults.sessionTreeCompaction ? { sessionTreeCompaction: value.sessionTreeCompaction } : {},
337
+ ...value.goalContinuation !== defaults.goalContinuation ? { goalContinuation: value.goalContinuation } : {}
338
+ };
339
+ return Object.keys(input).length > 0 ? input : void 0;
340
+ }
341
+
342
+ // src/adapters/config/parse-model-config.ts
343
+ function parseProvider(value, path3, issues) {
344
+ const normalized = parseOptionalTrimmedString(value, path3, issues);
345
+ if (!normalized) {
346
+ return void 0;
347
+ }
348
+ if (!isAgenrProvider(normalized)) {
349
+ pushIssue(issues, path3, "Expected a supported provider.");
350
+ return void 0;
351
+ }
352
+ return normalized;
353
+ }
354
+ function parseModelConfig(value, path3, issues) {
355
+ if (value === void 0) {
356
+ return void 0;
357
+ }
358
+ if (!isRecord(value)) {
359
+ pushIssue(issues, path3, "Expected an object.");
360
+ return void 0;
361
+ }
362
+ const startIndex = issues.length;
363
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["provider", "model"]), path3, issues);
364
+ const provider = parseProvider(value.provider, `${path3}.provider`, issues);
365
+ const model = parseOptionalTrimmedString(value.model, `${path3}.model`, issues);
366
+ if (!provider && !model) {
367
+ pushIssue(issues, path3, "Expected at least one of provider or model.");
368
+ }
369
+ if (issues.length > startIndex) {
370
+ return void 0;
371
+ }
372
+ return {
373
+ ...provider ? { provider } : {},
374
+ ...model ? { model } : {}
375
+ };
376
+ }
377
+ function hasModelConfig(value) {
378
+ return Boolean(value?.provider || value?.model);
379
+ }
380
+
381
+ // src/adapters/config/parse-dreaming-config.ts
382
+ function parseDreamingConfig(value, path3, issues) {
383
+ const defaults = createDefaultDreamingConfig();
384
+ if (value === void 0) {
385
+ return { resolved: defaults };
386
+ }
387
+ if (!isRecord(value)) {
388
+ pushIssue(issues, path3, "Expected an object.");
389
+ return { resolved: defaults };
390
+ }
391
+ const startIndex = issues.length;
392
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["model", "dailyCostCap", "tiers", "stages", "triggers"]), path3, issues);
393
+ const model = parseModelConfig(value.model, `${path3}.model`, issues);
394
+ const dailyCostCap = parseOptionalNonNegativeNumber(value.dailyCostCap, `${path3}.dailyCostCap`, issues);
395
+ const tiers = parseDreamingTiersConfig(value.tiers, `${path3}.tiers`, issues);
396
+ const stages = parseDreamingStagesConfig(value.stages, `${path3}.stages`, issues);
397
+ const triggers = parseDreamingTriggersConfig(value.triggers, `${path3}.triggers`, issues);
398
+ if (issues.length > startIndex) {
399
+ return { resolved: defaults };
400
+ }
401
+ const input = {
402
+ ...model ? { model } : {},
403
+ ...dailyCostCap !== void 0 ? { dailyCostCap } : {},
404
+ ...tiers.input ? { tiers: tiers.input } : {},
405
+ ...stages.input ? { stages: stages.input } : {},
406
+ ...triggers.input ? { triggers: triggers.input } : {}
407
+ };
408
+ return {
409
+ ...hasDreamingInput(input) ? { input } : {},
410
+ resolved: {
411
+ ...model ? { model } : {},
412
+ dailyCostCap: dailyCostCap ?? defaults.dailyCostCap,
413
+ tiers: tiers.resolved,
414
+ stages: stages.resolved,
415
+ triggers: triggers.resolved
416
+ }
417
+ };
418
+ }
419
+ function parseDreamingTiersConfig(value, path3, issues) {
420
+ const defaults = createDefaultDreamingConfig().tiers;
421
+ if (value === void 0) {
422
+ return { resolved: defaults };
423
+ }
424
+ if (!isRecord(value)) {
425
+ pushIssue(issues, path3, "Expected an object.");
426
+ return { resolved: defaults };
427
+ }
428
+ const startIndex = issues.length;
429
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["light", "standard", "deep"]), path3, issues);
430
+ const light = parseDreamingTierEnabledConfig(value.light, `${path3}.light`, issues);
431
+ const standard = parseDreamingTierEnabledConfig(value.standard, `${path3}.standard`, issues);
432
+ const deep = parseDreamingDeepTierConfig(value.deep, `${path3}.deep`, issues);
433
+ if (issues.length > startIndex) {
434
+ return { resolved: defaults };
435
+ }
436
+ const input = {
437
+ ...light.input ? { light: light.input } : {},
438
+ ...standard.input ? { standard: standard.input } : {},
439
+ ...deep.input ? { deep: deep.input } : {}
440
+ };
441
+ return {
442
+ ...Object.keys(input).length > 0 ? { input } : {},
443
+ resolved: {
444
+ light: { enabled: light.resolved.enabled ?? defaults.light.enabled },
445
+ standard: { enabled: standard.resolved.enabled ?? defaults.standard.enabled },
446
+ deep: {
447
+ enabled: deep.resolved.enabled ?? defaults.deep.enabled,
448
+ intervalHours: deep.resolved.intervalHours ?? defaults.deep.intervalHours
449
+ }
450
+ }
451
+ };
452
+ }
453
+ function parseDreamingTierEnabledConfig(value, path3, issues) {
454
+ if (value === void 0) {
455
+ return { resolved: {} };
456
+ }
457
+ if (!isRecord(value)) {
458
+ pushIssue(issues, path3, "Expected an object.");
459
+ return { resolved: {} };
460
+ }
461
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled"]), path3, issues);
462
+ const enabled = parseOptionalBoolean(value.enabled, `${path3}.enabled`, issues);
463
+ const input = enabled !== void 0 ? { enabled } : {};
464
+ return {
465
+ ...Object.keys(input).length > 0 ? { input } : {},
466
+ resolved: input
467
+ };
468
+ }
469
+ function parseDreamingDeepTierConfig(value, path3, issues) {
470
+ if (value === void 0) {
471
+ return { resolved: {} };
472
+ }
473
+ if (!isRecord(value)) {
474
+ pushIssue(issues, path3, "Expected an object.");
475
+ return { resolved: {} };
476
+ }
477
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled", "intervalHours"]), path3, issues);
478
+ const enabled = parseOptionalBoolean(value.enabled, `${path3}.enabled`, issues);
479
+ const intervalHours = parseOptionalIntegerInRange(value.intervalHours, `${path3}.intervalHours`, issues, { min: 1 });
480
+ const input = {
481
+ ...enabled !== void 0 ? { enabled } : {},
482
+ ...intervalHours !== void 0 ? { intervalHours } : {}
483
+ };
484
+ return {
485
+ ...Object.keys(input).length > 0 ? { input } : {},
486
+ resolved: input
487
+ };
488
+ }
489
+ function parseDreamingStagesConfig(value, path3, issues) {
490
+ const defaults = createDefaultDreamingConfig().stages;
491
+ if (value === void 0) {
492
+ return { resolved: defaults };
493
+ }
494
+ if (!isRecord(value)) {
495
+ pushIssue(issues, path3, "Expected an object.");
496
+ return { resolved: defaults };
497
+ }
498
+ const startIndex = issues.length;
499
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["extract", "project", "prune"]), path3, issues);
500
+ const extract = parseDreamingExtractConfig(value.extract, `${path3}.extract`, issues);
501
+ const project = parseDreamingProjectConfig(value.project, `${path3}.project`, issues);
502
+ const prune = parseDreamingPruneConfig(value.prune, `${path3}.prune`, issues);
503
+ if (issues.length > startIndex) {
504
+ return { resolved: defaults };
505
+ }
506
+ const input = {
507
+ ...extract.input ? { extract: extract.input } : {},
508
+ ...project.input ? { project: project.input } : {},
509
+ ...prune.input ? { prune: prune.input } : {}
510
+ };
511
+ return {
512
+ ...Object.keys(input).length > 0 ? { input } : {},
513
+ resolved: {
514
+ extract: extract.resolved,
515
+ project: project.resolved,
516
+ prune: prune.resolved
517
+ }
518
+ };
519
+ }
520
+ function parseDreamingExtractConfig(value, path3, issues) {
521
+ const defaults = createDefaultDreamingConfig().stages.extract;
522
+ if (value === void 0) {
523
+ return { resolved: defaults };
524
+ }
525
+ if (!isRecord(value)) {
526
+ pushIssue(issues, path3, "Expected an object.");
527
+ return { resolved: defaults };
528
+ }
529
+ const startIndex = issues.length;
530
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["maxSessionsPerRun", "lightMaxSessionsPerRun", "contextLookup"]), path3, issues);
531
+ const maxSessionsPerRun = parseOptionalIntegerInRange(value.maxSessionsPerRun, `${path3}.maxSessionsPerRun`, issues, { min: 1 });
532
+ const lightMaxSessionsPerRun = parseOptionalIntegerInRange(value.lightMaxSessionsPerRun, `${path3}.lightMaxSessionsPerRun`, issues, { min: 1 });
533
+ const contextLookup = parseDreamingContextLookupConfig(value.contextLookup, `${path3}.contextLookup`, issues);
534
+ if (issues.length > startIndex) {
535
+ return { resolved: defaults };
536
+ }
537
+ const input = {
538
+ ...maxSessionsPerRun !== void 0 ? { maxSessionsPerRun } : {},
539
+ ...lightMaxSessionsPerRun !== void 0 ? { lightMaxSessionsPerRun } : {},
540
+ ...contextLookup.input ? { contextLookup: contextLookup.input } : {}
541
+ };
542
+ return {
543
+ ...Object.keys(input).length > 0 ? { input } : {},
544
+ resolved: {
545
+ maxSessionsPerRun: maxSessionsPerRun ?? defaults.maxSessionsPerRun,
546
+ lightMaxSessionsPerRun: lightMaxSessionsPerRun ?? defaults.lightMaxSessionsPerRun,
547
+ contextLookup: contextLookup.resolved
548
+ }
549
+ };
550
+ }
551
+ function parseDreamingContextLookupConfig(value, path3, issues) {
552
+ const defaults = createDefaultDreamingConfig().stages.extract.contextLookup;
553
+ if (value === void 0) {
554
+ return { resolved: defaults };
555
+ }
556
+ if (!isRecord(value)) {
557
+ pushIssue(issues, path3, "Expected an object.");
558
+ return { resolved: defaults };
559
+ }
560
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled"]), path3, issues);
561
+ const enabled = parseOptionalBoolean(value.enabled, `${path3}.enabled`, issues);
562
+ const input = {
563
+ ...enabled !== void 0 ? { enabled } : {}
564
+ };
565
+ return {
566
+ ...Object.keys(input).length > 0 ? { input } : {},
567
+ resolved: {
568
+ enabled: enabled ?? defaults.enabled
569
+ }
570
+ };
571
+ }
572
+ function parseDreamingProjectConfig(value, path3, issues) {
573
+ const defaults = createDefaultDreamingConfig().stages.project;
574
+ if (value === void 0) {
575
+ return { resolved: defaults };
576
+ }
577
+ if (!isRecord(value)) {
578
+ pushIssue(issues, path3, "Expected an object.");
579
+ return { resolved: defaults };
580
+ }
581
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["maxProfileDurables"]), path3, issues);
582
+ const maxProfileDurables = parseOptionalIntegerInRange(value.maxProfileDurables, `${path3}.maxProfileDurables`, issues, { min: 1 });
583
+ const input = {
584
+ ...maxProfileDurables !== void 0 ? { maxProfileDurables } : {}
585
+ };
586
+ return {
587
+ ...Object.keys(input).length > 0 ? { input } : {},
588
+ resolved: {
589
+ maxProfileDurables: maxProfileDurables ?? defaults.maxProfileDurables
590
+ }
591
+ };
592
+ }
593
+ function parseDreamingPruneConfig(value, path3, issues) {
594
+ const defaults = createDefaultDreamingPruneConfig();
595
+ if (value === void 0) {
596
+ return { resolved: defaults };
597
+ }
598
+ if (!isRecord(value)) {
599
+ pushIssue(issues, path3, "Expected an object.");
600
+ return { resolved: defaults };
601
+ }
602
+ const startIndex = issues.length;
603
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["protectRecalledDays", "protectMinImportance"]), path3, issues);
604
+ const protectRecalledDays = parseOptionalIntegerInRange(value.protectRecalledDays, `${path3}.protectRecalledDays`, issues, { min: 0 });
605
+ const protectMinImportance = parseOptionalIntegerInRange(value.protectMinImportance, `${path3}.protectMinImportance`, issues, { min: 0 });
606
+ if (issues.length > startIndex) {
607
+ return { resolved: defaults };
608
+ }
609
+ const input = {
610
+ ...protectRecalledDays !== void 0 ? { protectRecalledDays } : {},
611
+ ...protectMinImportance !== void 0 ? { protectMinImportance } : {}
612
+ };
613
+ return {
614
+ ...Object.keys(input).length > 0 ? { input } : {},
615
+ resolved: {
616
+ protectRecalledDays: protectRecalledDays ?? defaults.protectRecalledDays,
617
+ protectMinImportance: protectMinImportance ?? defaults.protectMinImportance
618
+ }
619
+ };
620
+ }
621
+ function parseDreamingTriggersConfig(value, path3, issues) {
622
+ const defaults = createDefaultDreamingConfig().triggers;
623
+ if (value === void 0) {
624
+ return { resolved: defaults };
625
+ }
626
+ if (!isRecord(value)) {
627
+ pushIssue(issues, path3, "Expected an object.");
628
+ return { resolved: defaults };
629
+ }
630
+ const startIndex = issues.length;
631
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["postSessionLightDream", "importanceThreshold", "minIntervalMinutes"]), path3, issues);
632
+ const postSessionLightDream = parseOptionalBoolean(value.postSessionLightDream, `${path3}.postSessionLightDream`, issues);
633
+ const importanceThreshold = parseOptionalIntegerInRange(value.importanceThreshold, `${path3}.importanceThreshold`, issues, { min: 0 });
634
+ const minIntervalMinutes = parseOptionalIntegerInRange(value.minIntervalMinutes, `${path3}.minIntervalMinutes`, issues, { min: 0 });
635
+ if (issues.length > startIndex) {
636
+ return { resolved: defaults };
637
+ }
638
+ const input = {
639
+ ...postSessionLightDream !== void 0 ? { postSessionLightDream } : {},
640
+ ...importanceThreshold !== void 0 ? { importanceThreshold } : {},
641
+ ...minIntervalMinutes !== void 0 ? { minIntervalMinutes } : {}
642
+ };
643
+ return {
644
+ ...Object.keys(input).length > 0 ? { input } : {},
645
+ resolved: {
646
+ postSessionLightDream: postSessionLightDream ?? defaults.postSessionLightDream,
647
+ importanceThreshold: importanceThreshold ?? defaults.importanceThreshold,
648
+ minIntervalMinutes: minIntervalMinutes ?? defaults.minIntervalMinutes
649
+ }
650
+ };
651
+ }
652
+ function parseOptionalNonNegativeNumber(value, path3, issues) {
653
+ if (value === void 0) {
654
+ return void 0;
655
+ }
656
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
657
+ pushIssue(issues, path3, "Expected a non-negative number.");
658
+ return void 0;
659
+ }
660
+ return value;
661
+ }
662
+ function createDefaultDreamingConfig() {
663
+ return {
664
+ dailyCostCap: DEFAULT_DREAMING_DAILY_COST_CAP,
665
+ tiers: {
666
+ light: { enabled: true },
667
+ standard: { enabled: true },
668
+ deep: { enabled: true, intervalHours: DEFAULT_DREAMING_DEEP_INTERVAL_HOURS }
669
+ },
670
+ stages: {
671
+ extract: {
672
+ maxSessionsPerRun: DEFAULT_DREAMING_EXTRACT_MAX_SESSIONS,
673
+ lightMaxSessionsPerRun: DEFAULT_DREAMING_LIGHT_MAX_SESSIONS,
674
+ contextLookup: {
675
+ enabled: true
676
+ }
677
+ },
678
+ project: { maxProfileDurables: DEFAULT_DREAMING_MAX_PROFILE_DURABLES },
679
+ prune: createDefaultDreamingPruneConfig()
680
+ },
681
+ triggers: {
682
+ postSessionLightDream: true,
683
+ importanceThreshold: DEFAULT_DREAMING_IMPORTANCE_THRESHOLD,
684
+ minIntervalMinutes: DEFAULT_DREAMING_MIN_INTERVAL_MINUTES
685
+ }
686
+ };
687
+ }
688
+ function createDefaultDreamingPruneConfig() {
689
+ return {
690
+ protectRecalledDays: DEFAULT_DREAMING_PRUNE_PROTECT_RECALLED_DAYS,
691
+ protectMinImportance: DEFAULT_DREAMING_PRUNE_PROTECT_MIN_IMPORTANCE
692
+ };
693
+ }
694
+ function hasDreamingInput(value) {
695
+ return hasModelConfig(value.model) || value.dailyCostCap !== void 0 || value.tiers !== void 0 || value.stages?.extract !== void 0 || value.stages?.project !== void 0 || value.stages?.prune !== void 0 || value.triggers !== void 0;
696
+ }
697
+ function toDreamingInput(value) {
698
+ const tiers = value.tiers;
699
+ const tiersInput = {
700
+ ...tiers.light.enabled !== true ? { light: { enabled: tiers.light.enabled } } : {},
701
+ ...tiers.standard.enabled !== true ? { standard: { enabled: tiers.standard.enabled } } : {},
702
+ ...tiers.deep.enabled !== true || tiers.deep.intervalHours !== DEFAULT_DREAMING_DEEP_INTERVAL_HOURS ? {
703
+ deep: {
704
+ ...tiers.deep.enabled !== true ? { enabled: tiers.deep.enabled } : {},
705
+ ...tiers.deep.intervalHours !== DEFAULT_DREAMING_DEEP_INTERVAL_HOURS ? { intervalHours: tiers.deep.intervalHours } : {}
706
+ }
707
+ } : {}
708
+ };
709
+ const extract = value.stages.extract;
710
+ const contextLookup = extract.contextLookup;
711
+ const contextLookupInput = {
712
+ ...contextLookup.enabled !== true ? { enabled: contextLookup.enabled } : {}
713
+ };
714
+ const extractInput = {
715
+ ...extract.maxSessionsPerRun !== DEFAULT_DREAMING_EXTRACT_MAX_SESSIONS ? { maxSessionsPerRun: extract.maxSessionsPerRun } : {},
716
+ ...extract.lightMaxSessionsPerRun !== DEFAULT_DREAMING_LIGHT_MAX_SESSIONS ? { lightMaxSessionsPerRun: extract.lightMaxSessionsPerRun } : {},
717
+ ...Object.keys(contextLookupInput).length > 0 ? { contextLookup: contextLookupInput } : {}
718
+ };
719
+ const project = value.stages.project;
720
+ const projectInput = {
721
+ ...project.maxProfileDurables !== DEFAULT_DREAMING_MAX_PROFILE_DURABLES ? { maxProfileDurables: project.maxProfileDurables } : {}
722
+ };
723
+ const prune = value.stages.prune;
724
+ const pruneInput = {
725
+ ...prune.protectRecalledDays !== DEFAULT_DREAMING_PRUNE_PROTECT_RECALLED_DAYS ? { protectRecalledDays: prune.protectRecalledDays } : {},
726
+ ...prune.protectMinImportance !== DEFAULT_DREAMING_PRUNE_PROTECT_MIN_IMPORTANCE ? { protectMinImportance: prune.protectMinImportance } : {}
727
+ };
728
+ const triggers = value.triggers;
729
+ const triggersInput = {
730
+ ...triggers.postSessionLightDream !== true ? { postSessionLightDream: triggers.postSessionLightDream } : {},
731
+ ...triggers.importanceThreshold !== DEFAULT_DREAMING_IMPORTANCE_THRESHOLD ? { importanceThreshold: triggers.importanceThreshold } : {},
732
+ ...triggers.minIntervalMinutes !== DEFAULT_DREAMING_MIN_INTERVAL_MINUTES ? { minIntervalMinutes: triggers.minIntervalMinutes } : {}
733
+ };
734
+ const stagesInput = {
735
+ ...Object.keys(extractInput).length > 0 ? { extract: extractInput } : {},
736
+ ...Object.keys(projectInput).length > 0 ? { project: projectInput } : {},
737
+ ...Object.keys(pruneInput).length > 0 ? { prune: pruneInput } : {}
738
+ };
739
+ const input = {
740
+ ...hasModelConfig(value.model) ? { model: value.model } : {},
741
+ ...value.dailyCostCap !== DEFAULT_DREAMING_DAILY_COST_CAP ? { dailyCostCap: value.dailyCostCap } : {},
742
+ ...Object.keys(tiersInput).length > 0 ? { tiers: tiersInput } : {},
743
+ ...Object.keys(stagesInput).length > 0 ? { stages: stagesInput } : {},
744
+ ...Object.keys(triggersInput).length > 0 ? { triggers: triggersInput } : {}
745
+ };
746
+ return hasDreamingInput(input) ? input : void 0;
747
+ }
748
+
749
+ // src/adapters/config/parse-agenr-config.ts
750
+ function parseAgenrConfig(value, options) {
751
+ const normalized = normalizeAgenrConfig(value, options);
752
+ return normalized.ok ? { ok: true, value: normalized.resolved } : normalized;
753
+ }
754
+ function canonicalizeAgenrConfigInput(value, options) {
755
+ const normalized = normalizeAgenrConfig(value, options);
756
+ return normalized.ok ? { ok: true, value: normalized.input } : normalized;
757
+ }
758
+ function toAgenrConfigInput(config, options = {}) {
759
+ const input = {
760
+ ...config.auth ? { auth: config.auth } : {},
761
+ ...config.provider ? { provider: config.provider } : {},
762
+ ...config.model ? { model: config.model } : {},
763
+ ...hasStoredCredentials(config.credentials) ? { credentials: config.credentials } : {},
764
+ ...config.embeddingModel ? { embeddingModel: config.embeddingModel } : {},
765
+ ...config.extractionContext ? { extractionContext: config.extractionContext } : {},
766
+ ...hasModelConfig(config.extractionModel) ? { extractionModel: config.extractionModel } : {},
767
+ ...hasModelConfig(config.dedupModel) ? { dedupModel: config.dedupModel } : {},
768
+ ...hasModelConfig(config.episodeModel) ? { episodeModel: config.episodeModel } : {},
769
+ ...hasModelConfig(config.crossEncoderModel) ? { crossEncoderModel: config.crossEncoderModel } : {}
770
+ };
771
+ const features = toFeatureFlagInput(config.features);
772
+ if (features) {
773
+ input.features = features;
774
+ }
775
+ const claimExtraction = toClaimExtractionInput(config.claimExtraction);
776
+ if (claimExtraction) {
777
+ input.claimExtraction = claimExtraction;
778
+ }
779
+ const dreaming = toDreamingInput(config.dreaming);
780
+ if (dreaming) {
781
+ input.dreaming = dreaming;
782
+ }
783
+ if (config.dbPath !== options.defaultDbPath) {
784
+ input.dbPath = config.dbPath;
785
+ }
786
+ if (config.apiPort !== DEFAULT_API_PORT) {
787
+ input.apiPort = config.apiPort;
788
+ }
789
+ return input;
790
+ }
791
+ function normalizeAgenrConfig(value, options) {
792
+ const issues = [];
793
+ const claimDefaults = createDefaultClaimExtractionConfig();
794
+ const dreamingDefaults = createDefaultDreamingConfig();
795
+ if (value === void 0) {
796
+ return {
797
+ ok: true,
798
+ input: {},
799
+ resolved: {
800
+ claimExtraction: claimDefaults,
801
+ dreaming: dreamingDefaults,
802
+ features: { ...DEFAULT_AGENR_FEATURE_FLAGS },
803
+ dbPath: options.defaultDbPath,
804
+ apiPort: DEFAULT_API_PORT
805
+ }
806
+ };
807
+ }
808
+ if (!isRecord(value)) {
809
+ return {
810
+ ok: false,
811
+ issues: [{ path: "config", message: "Expected a JSON object." }]
812
+ };
813
+ }
814
+ pushTopLevelIssues(value, issues);
815
+ const auth = parseAuth(value.auth, "auth", issues);
816
+ const provider = parseProvider(value.provider, "provider", issues);
817
+ const model = parseOptionalTrimmedString(value.model, "model", issues);
818
+ const credentials = parseCredentials(value.credentials, "credentials", issues);
819
+ const embeddingModel = parseOptionalTrimmedString(value.embeddingModel, "embeddingModel", issues);
820
+ const extractionContext = parseOptionalTrimmedString(value.extractionContext, "extractionContext", issues);
821
+ const extractionModel = parseModelConfig(value.extractionModel, "extractionModel", issues);
822
+ const dedupModel = parseModelConfig(value.dedupModel, "dedupModel", issues);
823
+ const episodeModel = parseModelConfig(value.episodeModel, "episodeModel", issues);
824
+ const crossEncoderModel = parseModelConfig(value.crossEncoderModel, "crossEncoderModel", issues);
825
+ const claimExtraction = parseClaimExtractionConfig(value.claimExtraction, "claimExtraction", issues);
826
+ const dreaming = parseDreamingConfig(value.dreaming, "dreaming", issues);
827
+ const features = parseFeatureFlags(value.features, "features", issues);
828
+ const dbPath = parseOptionalTrimmedString(value.dbPath, "dbPath", issues);
829
+ const apiPort = parseOptionalIntegerInRange(value.apiPort, "apiPort", issues, {
830
+ min: 1,
831
+ max: 65535
832
+ });
833
+ if (auth && provider && authMethodToProvider(auth) !== provider) {
834
+ pushIssue(issues, "provider", `Provider "${provider}" does not match auth method "${auth}".`);
835
+ }
836
+ if (issues.length > 0) {
837
+ return {
838
+ ok: false,
839
+ issues
840
+ };
841
+ }
842
+ const input = {
843
+ ...auth ? { auth } : {},
844
+ ...provider ? { provider } : {},
845
+ ...model ? { model } : {},
846
+ ...credentials ? { credentials } : {},
847
+ ...embeddingModel ? { embeddingModel } : {},
848
+ ...extractionContext ? { extractionContext } : {},
849
+ ...extractionModel ? { extractionModel } : {},
850
+ ...dedupModel ? { dedupModel } : {},
851
+ ...episodeModel ? { episodeModel } : {},
852
+ ...crossEncoderModel ? { crossEncoderModel } : {},
853
+ ...claimExtraction.input ? { claimExtraction: claimExtraction.input } : {},
854
+ ...dreaming.input ? { dreaming: dreaming.input } : {},
855
+ ...features.input ? { features: features.input } : {},
856
+ ...dbPath ? { dbPath } : {},
857
+ ...apiPort !== void 0 ? { apiPort } : {}
858
+ };
859
+ return {
860
+ ok: true,
861
+ input,
862
+ resolved: {
863
+ ...auth ? { auth } : {},
864
+ ...provider ? { provider } : {},
865
+ ...model ? { model } : {},
866
+ ...credentials ? { credentials } : {},
867
+ ...embeddingModel ? { embeddingModel } : {},
868
+ ...extractionContext ? { extractionContext } : {},
869
+ ...extractionModel ? { extractionModel } : {},
870
+ ...dedupModel ? { dedupModel } : {},
871
+ ...episodeModel ? { episodeModel } : {},
872
+ ...crossEncoderModel ? { crossEncoderModel } : {},
873
+ claimExtraction: claimExtraction.resolved,
874
+ dreaming: dreaming.resolved,
875
+ features: features.resolved,
876
+ dbPath: dbPath ?? options.defaultDbPath,
877
+ apiPort: apiPort ?? DEFAULT_API_PORT
878
+ }
879
+ };
880
+ }
881
+ function pushTopLevelIssues(value, issues) {
882
+ const allowedKeys = /* @__PURE__ */ new Set([
883
+ "auth",
884
+ "provider",
885
+ "model",
886
+ "credentials",
887
+ "embeddingModel",
888
+ "extractionContext",
889
+ "extractionModel",
890
+ "dedupModel",
891
+ "episodeModel",
892
+ "crossEncoderModel",
893
+ "claimExtraction",
894
+ "dreaming",
895
+ "features",
896
+ "dbPath",
897
+ "apiPort",
898
+ "apiKey",
899
+ "embeddingApiKey"
900
+ ]);
901
+ pushUnexpectedFields(value, allowedKeys, "", issues);
902
+ if ("apiKey" in value) {
903
+ pushIssue(issues, "apiKey", "Removed field. Move this value to credentials.openaiApiKey or credentials.anthropicApiKey, then delete apiKey.");
904
+ }
905
+ if ("embeddingApiKey" in value) {
906
+ pushIssue(issues, "embeddingApiKey", "Removed field. Move this value to credentials.openaiApiKey, then delete embeddingApiKey.");
907
+ }
908
+ if ("surgeon" in value) {
909
+ pushIssue(issues, "surgeon", 'Removed field. Rename the top-level "surgeon" block to "dreaming", then delete surgeon.');
910
+ }
911
+ }
912
+ function parseAuth(value, path3, issues) {
913
+ const normalized = parseOptionalTrimmedString(value, path3, issues);
914
+ if (!normalized) {
915
+ return void 0;
916
+ }
917
+ if (!isAgenrAuthMethod(normalized)) {
918
+ pushIssue(issues, path3, "Expected a supported auth method.");
919
+ return void 0;
920
+ }
921
+ return normalized;
922
+ }
923
+ function parseCredentials(value, path3, issues) {
924
+ if (value === void 0) {
925
+ return void 0;
926
+ }
927
+ if (!isRecord(value)) {
928
+ pushIssue(issues, path3, "Expected an object.");
929
+ return void 0;
930
+ }
931
+ const startIndex = issues.length;
932
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["openaiApiKey", "anthropicApiKey", "anthropicOauthToken"]), path3, issues);
933
+ const openaiApiKey = parseOptionalTrimmedString(value.openaiApiKey, `${path3}.openaiApiKey`, issues);
934
+ const anthropicApiKey = parseOptionalTrimmedString(value.anthropicApiKey, `${path3}.anthropicApiKey`, issues);
935
+ const anthropicOauthToken = parseOptionalTrimmedString(value.anthropicOauthToken, `${path3}.anthropicOauthToken`, issues);
936
+ if (issues.length > startIndex) {
937
+ return void 0;
938
+ }
939
+ const credentials = {
940
+ ...openaiApiKey ? { openaiApiKey } : {},
941
+ ...anthropicApiKey ? { anthropicApiKey } : {},
942
+ ...anthropicOauthToken ? { anthropicOauthToken } : {}
943
+ };
944
+ return hasStoredCredentials(credentials) ? credentials : void 0;
945
+ }
946
+ function parseClaimExtractionConfig(value, path3, issues) {
947
+ const defaults = createDefaultClaimExtractionConfig();
948
+ if (value === void 0) {
949
+ return {
950
+ resolved: defaults
951
+ };
952
+ }
953
+ if (!isRecord(value)) {
954
+ pushIssue(issues, path3, "Expected an object.");
955
+ return {
956
+ resolved: defaults
957
+ };
958
+ }
959
+ const startIndex = issues.length;
960
+ pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled", "confidenceThreshold", "eligibleTypes", "concurrency", "model"]), path3, issues);
961
+ const enabled = parseOptionalBoolean(value.enabled, `${path3}.enabled`, issues);
962
+ const confidenceThreshold = parseOptionalUnitInterval(value.confidenceThreshold, `${path3}.confidenceThreshold`, issues);
963
+ const eligibleTypes = parseEligibleTypes(value.eligibleTypes, `${path3}.eligibleTypes`, issues);
964
+ const concurrency = parseOptionalIntegerInRange(value.concurrency, `${path3}.concurrency`, issues, {
965
+ min: 1
966
+ });
967
+ const model = parseModelConfig(value.model, `${path3}.model`, issues);
968
+ if (issues.length > startIndex) {
969
+ return {
970
+ resolved: defaults
971
+ };
972
+ }
973
+ const input = {
974
+ ...enabled !== void 0 ? { enabled } : {},
975
+ ...confidenceThreshold !== void 0 ? { confidenceThreshold } : {},
976
+ ...eligibleTypes ? { eligibleTypes } : {},
977
+ ...concurrency !== void 0 ? { concurrency } : {},
978
+ ...model ? { model } : {}
979
+ };
980
+ return {
981
+ ...hasClaimExtractionInput(input) ? { input } : {},
982
+ resolved: {
983
+ enabled: enabled ?? defaults.enabled,
984
+ confidenceThreshold: confidenceThreshold ?? defaults.confidenceThreshold,
985
+ eligibleTypes: eligibleTypes ?? defaults.eligibleTypes,
986
+ concurrency: concurrency ?? defaults.concurrency,
987
+ ...model ? { model } : {}
988
+ }
989
+ };
990
+ }
991
+ function parseOptionalUnitInterval(value, path3, issues) {
992
+ if (value === void 0) {
993
+ return void 0;
994
+ }
995
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
996
+ pushIssue(issues, path3, "Expected a number from 0 to 1.");
997
+ return void 0;
998
+ }
999
+ return value;
1000
+ }
1001
+ function parseEligibleTypes(value, path3, issues) {
1002
+ if (value === void 0) {
1003
+ return void 0;
1004
+ }
1005
+ if (!Array.isArray(value)) {
1006
+ pushIssue(issues, path3, "Expected an array of entry types.");
1007
+ return void 0;
1008
+ }
1009
+ const normalized = [];
1010
+ const seen = /* @__PURE__ */ new Set();
1011
+ for (const [index, item] of value.entries()) {
1012
+ if (typeof item !== "string") {
1013
+ pushIssue(issues, `${path3}.${index}`, "Expected a supported entry type.");
1014
+ continue;
1015
+ }
1016
+ const trimmed = item.trim();
1017
+ if (!isDurableKind(trimmed)) {
1018
+ pushIssue(issues, `${path3}.${index}`, "Expected a supported entry type.");
1019
+ continue;
1020
+ }
1021
+ if (!seen.has(trimmed)) {
1022
+ seen.add(trimmed);
1023
+ normalized.push(trimmed);
1024
+ }
1025
+ }
1026
+ if (normalized.length === 0) {
1027
+ pushIssue(issues, path3, "Expected at least one supported entry type.");
1028
+ return void 0;
1029
+ }
1030
+ return normalized;
1031
+ }
1032
+ function createDefaultClaimExtractionConfig() {
1033
+ return {
1034
+ enabled: true,
1035
+ confidenceThreshold: DEFAULT_CLAIM_EXTRACTION_CONFIDENCE_THRESHOLD,
1036
+ eligibleTypes: [...DEFAULT_CLAIM_EXTRACTION_ELIGIBLE_TYPES],
1037
+ concurrency: DEFAULT_CLAIM_EXTRACTION_CONCURRENCY
1038
+ };
1039
+ }
1040
+ function hasStoredCredentials(credentials) {
1041
+ return Boolean(credentials?.openaiApiKey || credentials?.anthropicApiKey || credentials?.anthropicOauthToken);
1042
+ }
1043
+ function hasClaimExtractionInput(value) {
1044
+ return value.enabled !== void 0 || value.confidenceThreshold !== void 0 || value.eligibleTypes !== void 0 || value.concurrency !== void 0 || hasModelConfig(value.model);
1045
+ }
1046
+ function toClaimExtractionInput(value) {
1047
+ const input = {
1048
+ ...value.enabled !== true ? { enabled: value.enabled } : {},
1049
+ ...value.confidenceThreshold !== DEFAULT_CLAIM_EXTRACTION_CONFIDENCE_THRESHOLD ? { confidenceThreshold: value.confidenceThreshold } : {},
1050
+ ...!sameEligibleKinds(value.eligibleTypes, DEFAULT_CLAIM_EXTRACTION_ELIGIBLE_TYPES) ? { eligibleTypes: [...value.eligibleTypes] } : {},
1051
+ ...value.concurrency !== DEFAULT_CLAIM_EXTRACTION_CONCURRENCY ? { concurrency: value.concurrency } : {},
1052
+ ...hasModelConfig(value.model) ? { model: value.model } : {}
1053
+ };
1054
+ return hasClaimExtractionInput(input) ? input : void 0;
1055
+ }
1056
+
1057
+ // src/config.ts
1058
+ var DEFAULT_CONFIG_DIR = path2.join(os.homedir(), ".agenr");
1059
+ var DEFAULT_DB_NAME = "knowledge.db";
1060
+ var CONFIG_DIR_MODE = 448;
1061
+ var CONFIG_FILE_MODE = 384;
1062
+ function resolveConfigDir(env = process.env) {
1063
+ return env.AGENR_CONFIG_DIR ?? DEFAULT_CONFIG_DIR;
1064
+ }
1065
+ function resolveConfigPath(options = {}) {
1066
+ const env = options.env ?? process.env;
1067
+ const envConfigPath = normalizeOptionalString(env.AGENR_CONFIG_PATH);
1068
+ if (envConfigPath) {
1069
+ return envConfigPath;
1070
+ }
1071
+ const explicitConfigPath = normalizeOptionalString(options.configPath);
1072
+ if (explicitConfigPath) {
1073
+ return explicitConfigPath;
1074
+ }
1075
+ const adjacentConfigPath = resolveAdjacentConfigPath(options.dbPath);
1076
+ if (adjacentConfigPath) {
1077
+ return adjacentConfigPath;
1078
+ }
1079
+ return path2.join(resolveConfigDir(env), "config.json");
1080
+ }
1081
+ function resolveDbPath(config, env = process.env) {
1082
+ return normalizeOptionalString(env.AGENR_DB_PATH) ?? normalizeOptionalString(config?.dbPath) ?? resolvePersistedDefaultDbPath(env);
1083
+ }
1084
+ function resolveClaimExtractionConfig(config) {
1085
+ if (config && "enabled" in (config.claimExtraction ?? {})) {
1086
+ const claimExtraction = config.claimExtraction;
1087
+ if (typeof claimExtraction.enabled === "boolean" && typeof claimExtraction.confidenceThreshold === "number" && Array.isArray(claimExtraction.eligibleTypes) && typeof claimExtraction.concurrency === "number") {
1088
+ return {
1089
+ enabled: claimExtraction.enabled,
1090
+ confidenceThreshold: claimExtraction.confidenceThreshold,
1091
+ eligibleTypes: [...claimExtraction.eligibleTypes],
1092
+ concurrency: claimExtraction.concurrency
1093
+ };
1094
+ }
1095
+ }
1096
+ const parsed = parseAgenrConfig(
1097
+ {
1098
+ ...config?.claimExtraction ? { claimExtraction: config.claimExtraction } : {}
1099
+ },
1100
+ { defaultDbPath: resolvePersistedDefaultDbPath() }
1101
+ );
1102
+ if (!parsed.ok) {
1103
+ return {
1104
+ enabled: true,
1105
+ confidenceThreshold: DEFAULT_CLAIM_EXTRACTION_CONFIDENCE_THRESHOLD,
1106
+ eligibleTypes: [...DEFAULT_CLAIM_EXTRACTION_ELIGIBLE_TYPES],
1107
+ concurrency: DEFAULT_CLAIM_EXTRACTION_CONCURRENCY
1108
+ };
1109
+ }
1110
+ return {
1111
+ enabled: parsed.value.claimExtraction.enabled,
1112
+ confidenceThreshold: parsed.value.claimExtraction.confidenceThreshold,
1113
+ eligibleTypes: [...parsed.value.claimExtraction.eligibleTypes],
1114
+ concurrency: parsed.value.claimExtraction.concurrency
1115
+ };
1116
+ }
1117
+ function readConfig(options = {}) {
1118
+ const configPath = resolveConfigFilesystemPath(resolveConfigPath(options));
1119
+ const defaultDbPath = resolveReadDefaultDbPath(options);
1120
+ if (!fs.existsSync(configPath)) {
1121
+ const parsed2 = parseAgenrConfig(void 0, { defaultDbPath });
1122
+ if (!parsed2.ok) {
1123
+ throw new Error("Internal config parser failure for empty config.");
1124
+ }
1125
+ return parsed2.value;
1126
+ }
1127
+ let parsedJson;
1128
+ try {
1129
+ const raw = fs.readFileSync(configPath, "utf-8");
1130
+ parsedJson = JSON.parse(raw);
1131
+ } catch (error) {
1132
+ const message = error instanceof Error ? error.message : String(error);
1133
+ throw new Error(`Invalid agenr config at ${configPath}: JSON parse failed - ${message}`, {
1134
+ cause: error
1135
+ });
1136
+ }
1137
+ const parsed = parseAgenrConfig(parsedJson, { defaultDbPath });
1138
+ if (!parsed.ok) {
1139
+ throw new Error(formatConfigValidationError(configPath, parsed.issues));
1140
+ }
1141
+ return parsed.value;
1142
+ }
1143
+ function configFileExists(options = {}) {
1144
+ return fs.existsSync(resolveConfigFilesystemPath(resolveConfigPath(options)));
1145
+ }
1146
+ function writeConfig(config, options = {}) {
1147
+ const configPath = resolveConfigFilesystemPath(resolveConfigPath(options));
1148
+ const configDir = path2.dirname(configPath);
1149
+ const canonical = canonicalizeAgenrConfigInput(config, {
1150
+ defaultDbPath: resolvePersistedDefaultDbPath()
1151
+ });
1152
+ if (!canonical.ok) {
1153
+ throw new Error(formatConfigValidationError(configPath, canonical.issues));
1154
+ }
1155
+ fs.mkdirSync(configDir, { recursive: true, mode: CONFIG_DIR_MODE });
1156
+ try {
1157
+ fs.chmodSync(configDir, CONFIG_DIR_MODE);
1158
+ } catch {
1159
+ }
1160
+ fs.writeFileSync(configPath, `${JSON.stringify(canonical.value, null, 2)}
1161
+ `, {
1162
+ encoding: "utf-8",
1163
+ mode: CONFIG_FILE_MODE
1164
+ });
1165
+ try {
1166
+ fs.chmodSync(configPath, CONFIG_FILE_MODE);
1167
+ } catch {
1168
+ }
1169
+ }
1170
+ function resolveAdjacentConfigPath(dbPath) {
1171
+ const normalizedDbPath = normalizeOptionalString(dbPath);
1172
+ if (!normalizedDbPath || normalizedDbPath === ":memory:") {
1173
+ return void 0;
1174
+ }
1175
+ if (normalizedDbPath.startsWith("file:")) {
1176
+ const filePath = resolveLocalFilesystemPath(normalizedDbPath);
1177
+ return filePath ? path2.join(path2.dirname(filePath), "config.json") : void 0;
1178
+ }
1179
+ return path2.join(path2.dirname(normalizedDbPath), "config.json");
1180
+ }
1181
+ function normalizeOptionalString(value) {
1182
+ const normalized = value?.trim();
1183
+ return normalized && normalized.length > 0 ? normalized : void 0;
1184
+ }
1185
+ function resolvePersistedDefaultDbPath(env = process.env) {
1186
+ return path2.join(resolveConfigDir(env), DEFAULT_DB_NAME);
1187
+ }
1188
+ function resolveReadDefaultDbPath(options) {
1189
+ const env = options.env ?? process.env;
1190
+ return normalizeOptionalString(env.AGENR_DB_PATH) ?? normalizeOptionalString(options.dbPath) ?? resolvePersistedDefaultDbPath(env);
1191
+ }
1192
+ function formatConfigValidationError(configPath, issues) {
1193
+ const details = issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ");
1194
+ return `Invalid agenr config at ${configPath}: ${details}`;
1195
+ }
1196
+
1197
+ // src/core/directives/model.ts
1198
+ var MEMORY_DIRECTIVE_CLAIM_KEY_PREFIX = "user/memory_directive/";
1199
+ var DEFAULT_PROACTIVE_DIRECTIVE_TRIGGER = "session_start";
1200
+ var DEFAULT_ABSTAIN_DIRECTIVE_TRIGGER = "always";
1201
+ var MIN_DIRECTIVE_TOPIC_LENGTH = 2;
1202
+ function isDirectiveDurable(entry) {
1203
+ const claimKey = entry.claim_key?.trim();
1204
+ return entry.type === "directive" || claimKey !== void 0 && claimKey.startsWith(MEMORY_DIRECTIVE_CLAIM_KEY_PREFIX) && claimKey.length > MEMORY_DIRECTIVE_CLAIM_KEY_PREFIX.length;
1205
+ }
1206
+ function parseDirectiveTrigger(value) {
1207
+ if (typeof value !== "string") {
1208
+ return void 0;
1209
+ }
1210
+ const normalized = normalizeForDirective(value);
1211
+ if (DIRECTIVE_BASE_TRIGGERS.includes(normalized)) {
1212
+ return normalized;
1213
+ }
1214
+ if (!normalized.startsWith("topic:")) {
1215
+ return void 0;
1216
+ }
1217
+ const topic = normalizeForDirective(normalized.slice("topic:".length));
1218
+ return topic.length >= MIN_DIRECTIVE_TOPIC_LENGTH ? `topic:${topic}` : void 0;
1219
+ }
1220
+ function parseDirectivePolarity(value) {
1221
+ if (typeof value !== "string") {
1222
+ return void 0;
1223
+ }
1224
+ const normalized = normalizeForDirective(value);
1225
+ return DIRECTIVE_POLARITIES.includes(normalized) ? normalized : void 0;
1226
+ }
1227
+ function normalizeMemoryDirectiveClaimKey(value) {
1228
+ if (typeof value !== "string") {
1229
+ return void 0;
1230
+ }
1231
+ const segments = value.split("/").map((segment) => normalizeClaimKeySegment(segment)).filter((segment) => segment.length > 0);
1232
+ if (segments.length !== 3 || segments[0] !== "user" || segments[1] !== "memory_directive") {
1233
+ return void 0;
1234
+ }
1235
+ return `${MEMORY_DIRECTIVE_CLAIM_KEY_PREFIX}${segments[2]}`;
1236
+ }
1237
+ function parseDirectiveMetadata(entry) {
1238
+ if (!isDirectiveDurable(entry)) {
1239
+ return null;
1240
+ }
1241
+ const polarity = parseDirectivePolarity(entry.directive_polarity ?? "abstain");
1242
+ if (!polarity) {
1243
+ return null;
1244
+ }
1245
+ const trigger = entry.directive_trigger === void 0 ? defaultDirectiveTrigger(polarity) : parseDirectiveTrigger(entry.directive_trigger);
1246
+ return trigger ? { polarity, trigger } : null;
1247
+ }
1248
+ function isProactiveDirectiveDurable(entry) {
1249
+ return parseDirectiveMetadata(entry)?.polarity === "proactive";
1250
+ }
1251
+ function defaultDirectiveTrigger(polarity) {
1252
+ return polarity === "proactive" ? DEFAULT_PROACTIVE_DIRECTIVE_TRIGGER : DEFAULT_ABSTAIN_DIRECTIVE_TRIGGER;
1253
+ }
1254
+ function normalizeForDirective(value) {
1255
+ return value.replace(/\s+/gu, " ").trim().normalize("NFKC").toLocaleLowerCase();
1256
+ }
1257
+
1258
+ // src/core/store/embedding-text.ts
1259
+ function composeEmbeddingText(entry) {
1260
+ return `${entry.type}: ${entry.subject} - ${entry.content}`;
1261
+ }
1262
+
1263
+ // src/core/claim-key-lifecycle.ts
1264
+ var PRECOMPUTED_LIFECYCLE_FIELDS = ["claim_key_status", "claim_key_source", "claim_key_confidence", "claim_key_rationale"];
1265
+ function parseClaimKeyStatus(value) {
1266
+ return parseStringEnum(value, CLAIM_KEY_STATUSES);
1267
+ }
1268
+ function parseClaimKeySource(value) {
1269
+ return parseStringEnum(value, CLAIM_KEY_SOURCES);
1270
+ }
1271
+ function parseClaimSupportMode(value) {
1272
+ return parseStringEnum(value, CLAIM_SUPPORT_MODES);
1273
+ }
1274
+ function parseClaimKeyConfidence(value) {
1275
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1 ? value : void 0;
1276
+ }
1277
+ function requireClaimKeyStatus(value, label) {
1278
+ const parsed = parseClaimKeyStatus(value);
1279
+ if (!parsed) {
1280
+ throw new Error(`Invalid ${label}: expected one of ${CLAIM_KEY_STATUSES.join(", ")}.`);
1281
+ }
1282
+ return parsed;
1283
+ }
1284
+ function requireClaimKeySource(value, label) {
1285
+ const parsed = parseClaimKeySource(value);
1286
+ if (!parsed) {
1287
+ throw new Error(`Invalid ${label}: expected one of ${CLAIM_KEY_SOURCES.join(", ")}.`);
1288
+ }
1289
+ return parsed;
1290
+ }
1291
+ function requireClaimSupportMode(value, label) {
1292
+ const parsed = parseClaimSupportMode(value);
1293
+ if (!parsed) {
1294
+ throw new Error(`Invalid ${label}: expected one of ${CLAIM_SUPPORT_MODES.join(", ")}.`);
1295
+ }
1296
+ return parsed;
1297
+ }
1298
+ function hasPrecomputedClaimKeyLifecycleFields(input) {
1299
+ return PRECOMPUTED_LIFECYCLE_FIELDS.some((field) => input[field] !== void 0);
1300
+ }
1301
+ function buildManualClaimKeyLifecycle(params) {
1302
+ return {
1303
+ claim_key: params.claimKey,
1304
+ claim_key_raw: buildClaimKeyRaw(params.rawClaimKey, params.claimKey),
1305
+ claim_key_status: "trusted",
1306
+ claim_key_source: "manual",
1307
+ claim_key_confidence: 1,
1308
+ claim_key_rationale: "manual claim key supplied by caller",
1309
+ claim_support_source_kind: normalizeOptionalString2(params.supportSourceKind),
1310
+ claim_support_locator: normalizeOptionalString2(params.supportLocator),
1311
+ claim_support_observed_at: normalizeOptionalString2(params.supportObservedAt),
1312
+ claim_support_mode: params.supportMode
1313
+ };
1314
+ }
1315
+ function normalizeManualClaimKeyUpdate(params) {
1316
+ const normalized = normalizeLifecycleClaimKeyInput(params.claimKey, params.rawClaimKey, "claim_key");
1317
+ return {
1318
+ claimKey: normalized.claimKey,
1319
+ updateFields: lifecycleToUpdateFields(
1320
+ buildManualClaimKeyLifecycle({
1321
+ claimKey: normalized.claimKey,
1322
+ rawClaimKey: normalized.rawClaimKey,
1323
+ supportSourceKind: params.supportSourceKind,
1324
+ supportLocator: params.supportLocator,
1325
+ supportObservedAt: params.supportObservedAt,
1326
+ supportMode: params.supportMode
1327
+ })
1328
+ )
1329
+ };
1330
+ }
1331
+ function buildClaimKeyLifecycleUpdateFields(lifecycle) {
1332
+ return lifecycleToUpdateFields(lifecycle);
1333
+ }
1334
+ function buildClaimKeyLifecycleAuditDetails(lifecycle) {
1335
+ return {
1336
+ claim_key_raw: lifecycle.claim_key_raw,
1337
+ claim_key_status: lifecycle.claim_key_status,
1338
+ claim_key_source: lifecycle.claim_key_source,
1339
+ claim_key_confidence: lifecycle.claim_key_confidence,
1340
+ claim_key_rationale: lifecycle.claim_key_rationale
1341
+ };
1342
+ }
1343
+ function buildPrecomputedClaimKeyLifecycle(input) {
1344
+ const claimKey = normalizeOptionalString2(input.claim_key);
1345
+ const status = parseClaimKeyStatus(input.claim_key_status);
1346
+ const source = parseClaimKeySource(input.claim_key_source);
1347
+ const confidence = parseClaimKeyConfidence(input.claim_key_confidence);
1348
+ const rationale = normalizeOptionalString2(input.claim_key_rationale);
1349
+ const supportMode = parseClaimSupportMode(input.claim_support_mode);
1350
+ if (!claimKey || !status || !source || confidence === void 0 || !rationale) {
1351
+ return void 0;
1352
+ }
1353
+ return {
1354
+ claim_key: claimKey,
1355
+ claim_key_raw: buildClaimKeyRaw(input.claim_key_raw, claimKey),
1356
+ claim_key_status: status,
1357
+ claim_key_source: source,
1358
+ claim_key_confidence: confidence,
1359
+ claim_key_rationale: rationale,
1360
+ claim_support_source_kind: normalizeOptionalString2(input.claim_support_source_kind),
1361
+ claim_support_locator: normalizeOptionalString2(input.claim_support_locator),
1362
+ claim_support_observed_at: normalizeOptionalString2(input.claim_support_observed_at),
1363
+ claim_support_mode: supportMode
1364
+ };
1365
+ }
1366
+ function validateDirectClaimKeyLifecycleUpdate(fields) {
1367
+ if (!hasDirectLifecycleFields(fields)) {
1368
+ return void 0;
1369
+ }
1370
+ const missingRequired = REQUIRED_DIRECT_LIFECYCLE_FIELDS.filter((field) => fields[field] === void 0);
1371
+ if (missingRequired.length > 0) {
1372
+ throw new Error(`Direct claim-key lifecycle updates require a complete lifecycle payload. Missing: ${missingRequired.join(", ")}.`);
1373
+ }
1374
+ const normalizedClaimKey = normalizeLifecycleClaimKeyInput(fields.claim_key, fields.claim_key_raw, "claim_key");
1375
+ const claimSupportObservedAt = normalizeOptionalString2(fields.claim_support_observed_at);
1376
+ if (claimSupportObservedAt !== void 0 && Number.isNaN(Date.parse(claimSupportObservedAt))) {
1377
+ throw new Error("Invalid claim_support_observed_at: expected an ISO 8601 timestamp.");
1378
+ }
1379
+ const lifecycle = buildPrecomputedClaimKeyLifecycle({
1380
+ claim_key: normalizedClaimKey.claimKey,
1381
+ claim_key_raw: normalizedClaimKey.rawClaimKey,
1382
+ claim_key_status: requireClaimKeyStatus(fields.claim_key_status, "claim_key_status"),
1383
+ claim_key_source: requireClaimKeySource(fields.claim_key_source, "claim_key_source"),
1384
+ claim_key_confidence: requireClaimKeyConfidence(fields.claim_key_confidence, "claim_key_confidence"),
1385
+ claim_key_rationale: requireNonEmptyString(fields.claim_key_rationale, "claim_key_rationale"),
1386
+ claim_support_source_kind: normalizeOptionalString2(fields.claim_support_source_kind),
1387
+ claim_support_locator: normalizeOptionalString2(fields.claim_support_locator),
1388
+ claim_support_observed_at: claimSupportObservedAt,
1389
+ claim_support_mode: normalizeOptionalString2(fields.claim_support_mode) === void 0 ? void 0 : requireClaimSupportMode(fields.claim_support_mode, "claim_support_mode")
1390
+ });
1391
+ if (!lifecycle) {
1392
+ throw new Error("Direct claim-key lifecycle update could not be normalized.");
1393
+ }
1394
+ return lifecycle;
1395
+ }
1396
+ function buildExtractedClaimKeyLifecycle(extracted, supportContext = {}) {
1397
+ if (!extracted.claimKey) {
1398
+ return void 0;
1399
+ }
1400
+ const source = extracted.path;
1401
+ const rationalePrefix = source === "deterministic_repair" ? "claim key inferred by deterministic possessive-slot repair" : `claim key extracted from ${source} output`;
1402
+ return {
1403
+ claim_key: extracted.claimKey,
1404
+ claim_key_raw: buildClaimKeyRaw(formatExtractedRawClaimKey(extracted), extracted.claimKey),
1405
+ claim_key_status: source === "deterministic_repair" ? "tentative" : "trusted",
1406
+ claim_key_source: source,
1407
+ claim_key_confidence: extracted.confidence,
1408
+ claim_key_rationale: [rationalePrefix, extracted.compactionReason, extracted.acceptanceRationale].filter((value) => Boolean(value)).join("; "),
1409
+ claim_support_source_kind: normalizeOptionalString2(supportContext.sourceKind),
1410
+ claim_support_locator: normalizeOptionalString2(supportContext.locator),
1411
+ claim_support_observed_at: normalizeOptionalString2(supportContext.observedAt),
1412
+ claim_support_mode: supportContext.mode
1413
+ };
1414
+ }
1415
+ function applyClaimKeyLifecycle(entry, lifecycle) {
1416
+ entry.claim_key = lifecycle.claim_key;
1417
+ entry.claim_key_raw = lifecycle.claim_key_raw;
1418
+ entry.claim_key_status = lifecycle.claim_key_status;
1419
+ entry.claim_key_source = lifecycle.claim_key_source;
1420
+ entry.claim_key_confidence = lifecycle.claim_key_confidence;
1421
+ entry.claim_key_rationale = lifecycle.claim_key_rationale;
1422
+ entry.claim_support_source_kind = lifecycle.claim_support_source_kind;
1423
+ entry.claim_support_locator = lifecycle.claim_support_locator;
1424
+ entry.claim_support_observed_at = lifecycle.claim_support_observed_at;
1425
+ entry.claim_support_mode = lifecycle.claim_support_mode;
1426
+ }
1427
+ function buildInferredIngestClaimKeySupportContext(entry) {
1428
+ const sourceFile = normalizeOptionalString2(entry.source_file);
1429
+ const sourceContext = normalizeOptionalString2(entry.source_context);
1430
+ const observedAt = normalizeOptionalString2(entry.claim_support_observed_at ?? entry.created_at);
1431
+ if (!sourceFile) {
1432
+ return {};
1433
+ }
1434
+ return {
1435
+ sourceKind: normalizeOptionalString2(entry.claim_support_source_kind) ?? "transcript_ingest",
1436
+ locator: normalizeOptionalString2(entry.claim_support_locator) ?? buildInferredIngestSupportLocator(sourceFile, observedAt, sourceContext),
1437
+ observedAt,
1438
+ mode: entry.claim_support_mode ?? "inferred"
1439
+ };
1440
+ }
1441
+ function buildExplicitClaimKeyPreservationMetadata(entry, context) {
1442
+ if (!entry.claim_key) {
1443
+ return {};
1444
+ }
1445
+ const claimSupportObservedAt = normalizeOptionalString2(entry.claim_support_observed_at ?? context.observedAt ?? entry.created_at);
1446
+ return {
1447
+ ...buildClaimKeyRaw(entry.claim_key_raw ?? entry.claim_key, entry.claim_key) !== void 0 ? { claim_key_raw: buildClaimKeyRaw(entry.claim_key_raw ?? entry.claim_key, entry.claim_key) } : {},
1448
+ ...normalizeOptionalString2(entry.claim_support_source_kind ?? context.sourceKind) !== void 0 ? { claim_support_source_kind: normalizeOptionalString2(entry.claim_support_source_kind ?? context.sourceKind) } : {},
1449
+ ...normalizeOptionalString2(entry.claim_support_locator ?? context.locator) !== void 0 ? { claim_support_locator: normalizeOptionalString2(entry.claim_support_locator ?? context.locator) } : {},
1450
+ ...claimSupportObservedAt !== void 0 ? { claim_support_observed_at: claimSupportObservedAt } : {},
1451
+ ...(entry.claim_support_mode ?? context.mode) !== void 0 ? { claim_support_mode: entry.claim_support_mode ?? context.mode } : {}
1452
+ };
1453
+ }
1454
+ function mergeExplicitClaimKeyMetadata(entry, candidate) {
1455
+ if (!candidate.claim_key) {
1456
+ return entry;
1457
+ }
1458
+ if (entry.claim_key && entry.claim_key !== candidate.claim_key) {
1459
+ return entry;
1460
+ }
1461
+ const preserved = buildExplicitClaimKeyPreservationMetadata(candidate, {});
1462
+ return {
1463
+ ...entry,
1464
+ claim_key: entry.claim_key ?? candidate.claim_key,
1465
+ claim_key_raw: entry.claim_key_raw ?? preserved.claim_key_raw,
1466
+ claim_support_source_kind: entry.claim_support_source_kind ?? preserved.claim_support_source_kind,
1467
+ claim_support_locator: entry.claim_support_locator ?? preserved.claim_support_locator,
1468
+ claim_support_observed_at: entry.claim_support_observed_at ?? preserved.claim_support_observed_at,
1469
+ claim_support_mode: entry.claim_support_mode ?? preserved.claim_support_mode
1470
+ };
1471
+ }
1472
+ function buildReconcileAppliedClaimKeyLifecycle(input) {
1473
+ const source = resolveReconcileClaimKeySource(input.source, input.compactness) ?? "dreaming_reconcile";
1474
+ return {
1475
+ rawClaimKey: resolveLifecycleRawClaimKey({
1476
+ targetClaimKey: input.targetClaimKey,
1477
+ priorClaimKeyRaw: input.priorClaimKeyRaw,
1478
+ rawClaimKey: input.rawClaimKey,
1479
+ priorClaimKey: input.priorClaimKey
1480
+ }),
1481
+ status: resolveReconcileClaimKeyStatus({
1482
+ proposedClaimKeys: [input.targetClaimKey],
1483
+ source: input.source,
1484
+ support: input.support,
1485
+ compactness: input.compactness
1486
+ }),
1487
+ source
1488
+ };
1489
+ }
1490
+ function buildReconcileAppliedClaimKeyLifecycleBundle(input) {
1491
+ const lifecycle = buildReconcileAppliedClaimKeyLifecycle(input);
1492
+ return {
1493
+ claim_key: input.targetClaimKey,
1494
+ claim_key_raw: lifecycle.rawClaimKey,
1495
+ claim_key_status: lifecycle.status,
1496
+ claim_key_source: lifecycle.source,
1497
+ claim_key_confidence: input.confidence,
1498
+ claim_key_rationale: input.rationale
1499
+ };
1500
+ }
1501
+ function buildReconcileProposalClaimKeyLifecycle(input) {
1502
+ const proposedClaimKeys = normalizeStringArray(input.proposedClaimKeys);
1503
+ const targetClaimKey = proposedClaimKeys[0];
1504
+ if (!targetClaimKey) {
1505
+ return {
1506
+ deferredUntilReview: true,
1507
+ proposedStatus: "unresolved"
1508
+ };
1509
+ }
1510
+ return {
1511
+ deferredUntilReview: true,
1512
+ proposedStatus: resolveReconcileClaimKeyStatus({
1513
+ proposedClaimKeys,
1514
+ source: input.source,
1515
+ support: input.support,
1516
+ compactness: input.compactness
1517
+ }),
1518
+ proposedSource: resolveReconcileClaimKeySource(input.source, input.compactness),
1519
+ proposedRawClaimKey: resolveLifecycleRawClaimKey({
1520
+ targetClaimKey,
1521
+ rawClaimKey: input.rawClaimKey
1522
+ })
1523
+ };
1524
+ }
1525
+ function buildReconcileProposalClaimKeyAuditDetails(lifecycle) {
1526
+ if (!lifecycle) {
1527
+ return {};
1528
+ }
1529
+ return {
1530
+ proposal_deferred_until_review: lifecycle.deferredUntilReview,
1531
+ proposal_claim_key_status: lifecycle.proposedStatus,
1532
+ proposal_claim_key_source: lifecycle.proposedSource,
1533
+ proposal_claim_key_raw: lifecycle.proposedRawClaimKey
1534
+ };
1535
+ }
1536
+ function resolveReconcileClaimKeySource(source, compactness) {
1537
+ if (source === "metadata_backfill_rewrite" || source === "metadata_rewrite") {
1538
+ return "dreaming_reconcile";
1539
+ }
1540
+ if (source === "trusted_group_reuse" || source === "mixed_group_consensus" || source === "entity_family_auto_convergence" || source === "entity_family_canonical_candidate" || source === "entity_family_collision") {
1541
+ return "dreaming_reconcile";
1542
+ }
1543
+ if (source === "normalize" || compactness?.compactedFrom) {
1544
+ return "dreaming_reconcile";
1545
+ }
1546
+ return parseClaimKeySource(source);
1547
+ }
1548
+ function resolveReconcileClaimKeyStatus(input) {
1549
+ if (normalizeStringArray(input.proposedClaimKeys).length === 0) {
1550
+ return "unresolved";
1551
+ }
1552
+ const lifecycleSource = resolveReconcileClaimKeySource(input.source, input.compactness);
1553
+ if (lifecycleSource === "deterministic_repair" && !input.support?.autoApplyClass) {
1554
+ return "tentative";
1555
+ }
1556
+ return "trusted";
1557
+ }
1558
+ function buildClaimKeyRaw(rawClaimKey, canonicalClaimKey) {
1559
+ const normalizedRawClaimKey = normalizeOptionalString2(rawClaimKey);
1560
+ if (!normalizedRawClaimKey || normalizedRawClaimKey === canonicalClaimKey) {
1561
+ return void 0;
1562
+ }
1563
+ return normalizedRawClaimKey;
1564
+ }
1565
+ function buildReconcileProposalLifecycleRationale(baseRationale, lifecycle) {
1566
+ const normalizedBase = baseRationale.trim();
1567
+ if (lifecycle.proposedStatus === "unresolved" || !lifecycle.proposedSource) {
1568
+ return `${normalizedBase} The entry stays unchanged until review because no safe lifecycle write is ready yet.`;
1569
+ }
1570
+ const rawText = lifecycle.proposedRawClaimKey ? ` and claim_key_raw "${lifecycle.proposedRawClaimKey}"` : "";
1571
+ return `${normalizedBase} The entry stays unchanged until review. If approved, the replacement would persist claim_key_status "${lifecycle.proposedStatus}" with claim_key_source "${lifecycle.proposedSource}"${rawText}.`;
1572
+ }
1573
+ function formatExtractedRawClaimKey(extracted) {
1574
+ const rawEntity = normalizeOptionalString2(extracted.rawEntity);
1575
+ const rawAttribute = normalizeOptionalString2(extracted.rawAttribute);
1576
+ if (!rawEntity || !rawAttribute) {
1577
+ return extracted.compactedFrom ?? void 0;
1578
+ }
1579
+ return `${rawEntity}/${rawAttribute}`;
1580
+ }
1581
+ function resolveLifecycleRawClaimKey(input) {
1582
+ const candidates = [input.priorClaimKeyRaw, input.rawClaimKey ?? void 0, input.priorClaimKey ?? void 0];
1583
+ for (const candidate of candidates) {
1584
+ const rawClaimKey = buildClaimKeyRaw(candidate, input.targetClaimKey);
1585
+ if (rawClaimKey) {
1586
+ return rawClaimKey;
1587
+ }
1588
+ }
1589
+ return void 0;
1590
+ }
1591
+ var DIRECT_LIFECYCLE_FIELDS = [
1592
+ "claim_key",
1593
+ "claim_key_raw",
1594
+ "claim_key_status",
1595
+ "claim_key_source",
1596
+ "claim_key_confidence",
1597
+ "claim_key_rationale",
1598
+ "claim_support_source_kind",
1599
+ "claim_support_locator",
1600
+ "claim_support_observed_at",
1601
+ "claim_support_mode"
1602
+ ];
1603
+ var REQUIRED_DIRECT_LIFECYCLE_FIELDS = [
1604
+ "claim_key",
1605
+ "claim_key_status",
1606
+ "claim_key_source",
1607
+ "claim_key_confidence",
1608
+ "claim_key_rationale"
1609
+ ];
1610
+ function hasDirectLifecycleFields(fields) {
1611
+ return DIRECT_LIFECYCLE_FIELDS.some((field) => fields[field] !== void 0);
1612
+ }
1613
+ function normalizeLifecycleClaimKeyInput(claimKey, rawClaimKey, label) {
1614
+ const normalizedClaimKeyInput = requireNonEmptyString(claimKey, label);
1615
+ const normalizedClaimKey = normalizeClaimKey(normalizedClaimKeyInput);
1616
+ if (!normalizedClaimKey.ok) {
1617
+ throw new Error(`Invalid ${label}: ${describeClaimKeyNormalizationFailure(normalizedClaimKey.reason)}. Use canonical entity/attribute format.`);
1618
+ }
1619
+ return {
1620
+ claimKey: normalizedClaimKey.value.claimKey,
1621
+ rawClaimKey: buildClaimKeyRaw(rawClaimKey ?? normalizedClaimKeyInput, normalizedClaimKey.value.claimKey)
1622
+ };
1623
+ }
1624
+ function lifecycleToUpdateFields(lifecycle) {
1625
+ return {
1626
+ claim_key: lifecycle.claim_key,
1627
+ claim_key_raw: lifecycle.claim_key_raw,
1628
+ claim_key_status: lifecycle.claim_key_status,
1629
+ claim_key_source: lifecycle.claim_key_source,
1630
+ claim_key_confidence: lifecycle.claim_key_confidence,
1631
+ claim_key_rationale: lifecycle.claim_key_rationale,
1632
+ claim_support_source_kind: lifecycle.claim_support_source_kind,
1633
+ claim_support_locator: lifecycle.claim_support_locator,
1634
+ claim_support_observed_at: lifecycle.claim_support_observed_at,
1635
+ claim_support_mode: lifecycle.claim_support_mode
1636
+ };
1637
+ }
1638
+ function buildInferredIngestSupportLocator(sourceFile, observedAt, sourceContext) {
1639
+ if (observedAt && sourceContext) {
1640
+ return `${sourceFile}#observed_at:${observedAt}#context:${encodeURIComponent(sourceContext)}`;
1641
+ }
1642
+ if (observedAt) {
1643
+ return `${sourceFile}#observed_at:${observedAt}`;
1644
+ }
1645
+ if (sourceContext) {
1646
+ return `${sourceFile}#context:${encodeURIComponent(sourceContext)}`;
1647
+ }
1648
+ return sourceFile;
1649
+ }
1650
+ function parseStringEnum(value, values) {
1651
+ return typeof value === "string" && values.includes(value) ? value : void 0;
1652
+ }
1653
+ function requireNonEmptyString(value, label) {
1654
+ const normalized = normalizeOptionalString2(value);
1655
+ if (!normalized) {
1656
+ throw new Error(`Invalid ${label}: expected a non-empty string.`);
1657
+ }
1658
+ return normalized;
1659
+ }
1660
+ function normalizeOptionalString2(value) {
1661
+ const normalized = value?.trim();
1662
+ return normalized && normalized.length > 0 ? normalized : void 0;
1663
+ }
1664
+ function requireClaimKeyConfidence(value, label) {
1665
+ const parsed = parseClaimKeyConfidence(value);
1666
+ if (parsed !== void 0) {
1667
+ return parsed;
1668
+ }
1669
+ throw new Error(`Invalid ${label}: expected a finite number between 0 and 1.`);
1670
+ }
1671
+ function normalizeStringArray(values) {
1672
+ return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
1673
+ }
1674
+
1675
+ export {
1676
+ toAbsoluteFileUrl,
1677
+ resolveLocalFilesystemPath,
1678
+ DURABLE_KINDS,
1679
+ EXPIRY_LEVELS,
1680
+ CLAIM_KEY_STATUSES,
1681
+ CLAIM_KEY_SOURCES,
1682
+ CLAIM_SUPPORT_MODES,
1683
+ EPISODE_ACTIVITY_LEVELS,
1684
+ PROCEDURE_STEP_KINDS,
1685
+ PROCEDURE_CONDITION_KINDS,
1686
+ PROCEDURE_SOURCE_KINDS,
1687
+ parseClaimKeyStatus,
1688
+ parseClaimKeySource,
1689
+ parseClaimSupportMode,
1690
+ parseClaimKeyConfidence,
1691
+ requireClaimKeyStatus,
1692
+ requireClaimKeySource,
1693
+ requireClaimSupportMode,
1694
+ hasPrecomputedClaimKeyLifecycleFields,
1695
+ buildManualClaimKeyLifecycle,
1696
+ normalizeManualClaimKeyUpdate,
1697
+ buildClaimKeyLifecycleUpdateFields,
1698
+ buildClaimKeyLifecycleAuditDetails,
1699
+ buildPrecomputedClaimKeyLifecycle,
1700
+ validateDirectClaimKeyLifecycleUpdate,
1701
+ buildExtractedClaimKeyLifecycle,
1702
+ applyClaimKeyLifecycle,
1703
+ buildInferredIngestClaimKeySupportContext,
1704
+ buildExplicitClaimKeyPreservationMetadata,
1705
+ mergeExplicitClaimKeyMetadata,
1706
+ buildReconcileAppliedClaimKeyLifecycleBundle,
1707
+ buildReconcileProposalClaimKeyLifecycle,
1708
+ buildReconcileProposalClaimKeyAuditDetails,
1709
+ buildReconcileProposalLifecycleRationale,
1710
+ isRecord,
1711
+ readOptionalTrimmedString,
1712
+ readOptionalFiniteNumber,
1713
+ pushIssue,
1714
+ pushUnexpectedFields,
1715
+ parseRequiredTrimmedString,
1716
+ parseOptionalTrimmedString,
1717
+ parseOptionalBoolean,
1718
+ parseOptionalIntegerInRange,
1719
+ parseOptionalTimestampString,
1720
+ AGENR_FEATURE_FLAG_KEYS,
1721
+ DEFAULT_AGENR_FEATURE_FLAGS,
1722
+ createAllEnabledFeatureFlagConfig,
1723
+ DEFAULT_DREAMING_DAILY_COST_CAP,
1724
+ DEFAULT_DREAMING_PRUNE_PROTECT_RECALLED_DAYS,
1725
+ DEFAULT_DREAMING_PRUNE_PROTECT_MIN_IMPORTANCE,
1726
+ DEFAULT_DREAMING_IMPORTANCE_THRESHOLD,
1727
+ DEFAULT_DREAMING_MIN_INTERVAL_MINUTES,
1728
+ DEFAULT_DREAMING_EXTRACT_MAX_SESSIONS,
1729
+ DEFAULT_DREAMING_LIGHT_MAX_SESSIONS,
1730
+ DEFAULT_CLAIM_EXTRACTION_CONCURRENCY,
1731
+ isAgenrAuthMethod,
1732
+ authMethodToProvider,
1733
+ getAuthMethodDefinition,
1734
+ toAgenrConfigInput,
1735
+ resolveConfigPath,
1736
+ resolveDbPath,
1737
+ resolveClaimExtractionConfig,
1738
+ readConfig,
1739
+ configFileExists,
1740
+ writeConfig,
1741
+ MEMORY_DIRECTIVE_CLAIM_KEY_PREFIX,
1742
+ isDirectiveDurable,
1743
+ parseDirectiveTrigger,
1744
+ parseDirectivePolarity,
1745
+ normalizeMemoryDirectiveClaimKey,
1746
+ parseDirectiveMetadata,
1747
+ isProactiveDirectiveDurable,
1748
+ defaultDirectiveTrigger,
1749
+ composeEmbeddingText
1750
+ };