agenr 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/dist/adapters/openclaw/index.js +6 -6
- package/dist/adapters/skeln/index.d.ts +61 -2
- package/dist/adapters/skeln/index.js +4 -4
- package/dist/{chunk-NOIZQRQV.js → chunk-6HY5F5FE.js} +2 -2
- package/dist/{chunk-NNO2V4GH.js → chunk-FMQTRTWE.js} +159 -122
- package/dist/{chunk-E2DHUFZK.js → chunk-KL6X2E3I.js} +3 -3
- package/dist/{chunk-EEEL53X4.js → chunk-TMDNFBBC.js} +1 -1
- package/dist/{chunk-V5CDMHRN.js → chunk-UEGURBBW.js} +1 -1
- package/dist/{chunk-JSVQILB3.js → chunk-ZAX3YSTU.js} +1 -1
- package/dist/cli.js +24 -27
- package/dist/internal-eval-server.js +3 -3
- package/dist/internal-recall-eval-server.js +3 -3
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [3.2.0] - 2026-06-02
|
|
6
|
+
|
|
7
|
+
Cross-platform packaging, CI smoke coverage, and path handling hardening release.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Repository checks now cover package smoke workflows across platforms.** The release adds local package smoke tooling, Windows simulation, Docker-based Linux checks, and a slimmer Windows CI workflow.
|
|
12
|
+
- **Path handling now has focused cross-platform helpers and tests.** Shared filesystem path utilities and test helpers cover Windows, Linux, and local temporary-path behavior.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **Package build and smoke scripts are more portable.** Root and plugin package scripts now avoid shell-specific assumptions and handle install paths consistently across supported platforms.
|
|
17
|
+
- **Skeln adapter imports now use explicit shared host types.** The Skeln adapter has a dedicated type boundary for host-facing imports, reducing package-resolution friction during plugin builds.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Windows package smoke tests are quoting-safe.** Smoke commands now pass arguments separately, preserve path quotes, avoid `npx`, and restore the `cmd.exe` npm shim path needed by Windows runs.
|
|
22
|
+
- **SQLite and temp-path tests now clean up safely on Windows.** Database and test cleanup paths avoid platform-sensitive deletion and quoting failures.
|
|
23
|
+
- **Line-ending and packaging behavior is more deterministic.** Repository checkout and packaging paths are hardened for Linux and Windows release validation.
|
|
24
|
+
|
|
25
|
+
### Validation
|
|
26
|
+
|
|
27
|
+
Changes since last push to `origin/master`:
|
|
28
|
+
|
|
29
|
+
- Add local package smoke, Windows simulation, and Docker Linux test runners
|
|
30
|
+
- Add a slim Windows CI workflow and deterministic LF checkout configuration
|
|
31
|
+
- Harden package smoke command quoting, argument passing, and npm shim handling on Windows
|
|
32
|
+
- Add shared filesystem path helpers and cross-platform test temp-path helpers
|
|
33
|
+
- Harden SQLite, temp path, Skeln adapter, and plugin build paths for cross-platform package validation
|
|
34
|
+
|
|
5
35
|
## [3.1.0] - 2026-05-31
|
|
6
36
|
|
|
7
37
|
Memory fetch tools, Skeln episode lifecycle hardening, and repository packaging cleanup release.
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
openClawTranscriptParser,
|
|
5
5
|
parseTuiSessionKey,
|
|
6
6
|
readOpenClawSessionsStore
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-ZAX3YSTU.js";
|
|
8
8
|
import {
|
|
9
9
|
BEFORE_TURN_DEBUG_ARTIFACT_DEFAULT_TOP_K,
|
|
10
10
|
BEFORE_TURN_DEBUG_ARTIFACT_MAX_TOP_K,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
runStoreMemoryTool,
|
|
44
44
|
runUpdateMemoryTool,
|
|
45
45
|
writeBoundedSingleTranscriptEpisode
|
|
46
|
-
} from "../../chunk-
|
|
46
|
+
} from "../../chunk-KL6X2E3I.js";
|
|
47
47
|
import {
|
|
48
48
|
asRecord,
|
|
49
49
|
buildEntryMemoryResolverPorts,
|
|
@@ -54,13 +54,13 @@ import {
|
|
|
54
54
|
resolveTargetEntry,
|
|
55
55
|
sanitizeFetchToolParams,
|
|
56
56
|
sanitizeUpdateToolParams
|
|
57
|
-
} from "../../chunk-
|
|
57
|
+
} from "../../chunk-TMDNFBBC.js";
|
|
58
58
|
import {
|
|
59
59
|
containsAgenrMemoryContext,
|
|
60
60
|
formatAgenrBeforeTurnRecall,
|
|
61
61
|
runBeforeTurn,
|
|
62
62
|
stripAgenrMemoryContext
|
|
63
|
-
} from "../../chunk-
|
|
63
|
+
} from "../../chunk-UEGURBBW.js";
|
|
64
64
|
import {
|
|
65
65
|
EMBEDDING_DIMENSIONS,
|
|
66
66
|
buildRecallToolDetails,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
sanitizeRecallToolParams,
|
|
70
70
|
sanitizeStoreToolParams,
|
|
71
71
|
truncate
|
|
72
|
-
} from "../../chunk-
|
|
72
|
+
} from "../../chunk-FMQTRTWE.js";
|
|
73
73
|
import {
|
|
74
74
|
resolveClaimSlotPolicy
|
|
75
75
|
} from "../../chunk-5LADPJ4C.js";
|
|
@@ -759,7 +759,7 @@ function registerAgenrOpenClawTools(api, servicesPromise, logger) {
|
|
|
759
759
|
var openclaw_plugin_default = {
|
|
760
760
|
id: "agenr",
|
|
761
761
|
name: "agenr",
|
|
762
|
-
version: "3.
|
|
762
|
+
version: "3.2.0",
|
|
763
763
|
description: "agenr memory plugin for OpenClaw",
|
|
764
764
|
kind: "memory",
|
|
765
765
|
contracts: {
|
|
@@ -1,7 +1,66 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TSchema } from 'typebox';
|
|
2
|
+
import { AgentToolResult, AgentMessage } from '@earendil-works/pi-agent-core';
|
|
2
3
|
import { C as ClaimSlotPolicyConfig, a as ClaimSlotPolicy } from '../../claim-slot-policy-CdrW_1l4.js';
|
|
3
4
|
import { E as EntryType, b as RecallPorts, r as ProcedureDatabasePort, t as Entry, u as DatabasePort, v as EpisodeDatabasePort, w as EmbeddingPort, L as LlmPort } from '../../ports-CpzWESmZ.js';
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
/** Minimal branch-entry shape needed for before-turn visibility filtering. */
|
|
7
|
+
interface SkelnBranchEntryLike {
|
|
8
|
+
/** Session tree entry discriminator. */
|
|
9
|
+
type?: unknown;
|
|
10
|
+
/** Session tree entry id. */
|
|
11
|
+
id?: unknown;
|
|
12
|
+
/** Parent id retained for compatibility with Skeln entries. */
|
|
13
|
+
parentId?: unknown;
|
|
14
|
+
/** Message payload when this is a message entry. */
|
|
15
|
+
message?: unknown;
|
|
16
|
+
/** First replayed entry after compaction when this is a compaction entry. */
|
|
17
|
+
firstKeptEntryId?: unknown;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Minimal Skeln extension API surface used by the agenr adapter. */
|
|
21
|
+
interface ExtensionAPI {
|
|
22
|
+
/** Reads one extension setting supplied by Skeln config. */
|
|
23
|
+
getSetting(key: string): unknown;
|
|
24
|
+
/** Registers one model-facing tool with the Skeln runtime. */
|
|
25
|
+
registerTool(tool: SkelnToolDefinition): void;
|
|
26
|
+
}
|
|
27
|
+
/** Minimal Skeln session manager surface used by the agenr adapter. */
|
|
28
|
+
interface SkelnSessionManager {
|
|
29
|
+
/** Returns the active Skeln session id. */
|
|
30
|
+
getSessionId(): string | number;
|
|
31
|
+
/** Returns the active session working directory. */
|
|
32
|
+
getCwd(): string;
|
|
33
|
+
/** Returns the active session JSONL file path when available. */
|
|
34
|
+
getSessionFile(): string;
|
|
35
|
+
/** Returns active branch entries visible to before-turn recall. */
|
|
36
|
+
getBranch(): SkelnBranchEntryLike[];
|
|
37
|
+
}
|
|
38
|
+
/** Minimal Skeln extension context surface used by the agenr adapter. */
|
|
39
|
+
interface ExtensionContext {
|
|
40
|
+
/** Current working directory when provided directly by newer Skeln hosts. */
|
|
41
|
+
cwd?: string;
|
|
42
|
+
/** Session manager for identity, cwd fallback, and transcript location. */
|
|
43
|
+
sessionManager: SkelnSessionManager;
|
|
44
|
+
}
|
|
45
|
+
/** Tool-update callback shape accepted by Skeln tool handlers. */
|
|
46
|
+
type SkelnToolUpdateCallback = (update: unknown) => void;
|
|
47
|
+
/** Minimal Skeln tool definition shape registered by the agenr adapter. */
|
|
48
|
+
interface SkelnToolDefinition {
|
|
49
|
+
/** Tool name exposed to the model. */
|
|
50
|
+
name: string;
|
|
51
|
+
/** Human-readable label shown by host UI. */
|
|
52
|
+
label?: string;
|
|
53
|
+
/** Tool description shown to the model and host UI. */
|
|
54
|
+
description: string;
|
|
55
|
+
/** Optional prompt snippet injected by Skeln. */
|
|
56
|
+
promptSnippet?: string;
|
|
57
|
+
/** Optional model-facing usage guidelines injected by Skeln. */
|
|
58
|
+
promptGuidelines?: string[];
|
|
59
|
+
/** TypeBox-compatible parameter schema. */
|
|
60
|
+
parameters?: TSchema;
|
|
61
|
+
/** Executes one Skeln tool call. */
|
|
62
|
+
execute(toolCallId: string, params: unknown, signal: AbortSignal | undefined, onUpdate: SkelnToolUpdateCallback | undefined, context: ExtensionContext): AgentToolResult<Record<string, unknown>> | Promise<AgentToolResult<Record<string, unknown>>>;
|
|
63
|
+
}
|
|
5
64
|
|
|
6
65
|
/**
|
|
7
66
|
* Canonical feature flags for staged working-memory, session-memory, and goal rollout.
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
runStoreMemoryTool,
|
|
41
41
|
runUpdateMemoryTool,
|
|
42
42
|
writeBoundedSingleTranscriptEpisode
|
|
43
|
-
} from "../../chunk-
|
|
43
|
+
} from "../../chunk-KL6X2E3I.js";
|
|
44
44
|
import {
|
|
45
45
|
asRecord,
|
|
46
46
|
createSingleTranscriptDiscoveryPort,
|
|
@@ -48,11 +48,11 @@ import {
|
|
|
48
48
|
formatTargetSelector,
|
|
49
49
|
sanitizeFetchToolParams,
|
|
50
50
|
sanitizeUpdateToolParams
|
|
51
|
-
} from "../../chunk-
|
|
51
|
+
} from "../../chunk-TMDNFBBC.js";
|
|
52
52
|
import {
|
|
53
53
|
formatAgenrBeforeTurnRecall,
|
|
54
54
|
runBeforeTurn
|
|
55
|
-
} from "../../chunk-
|
|
55
|
+
} from "../../chunk-UEGURBBW.js";
|
|
56
56
|
import {
|
|
57
57
|
AGENR_FEATURE_FLAG_KEYS,
|
|
58
58
|
DEFAULT_AGENR_FEATURE_FLAGS,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
readOptionalTrimmedString,
|
|
64
64
|
resolveLlmApiKey,
|
|
65
65
|
resolveModel
|
|
66
|
-
} from "../../chunk-
|
|
66
|
+
} from "../../chunk-FMQTRTWE.js";
|
|
67
67
|
import "../../chunk-5LADPJ4C.js";
|
|
68
68
|
|
|
69
69
|
// src/adapters/skeln/config.ts
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
formatAgenrBeforeTurnRecall,
|
|
14
14
|
runBeforeTurn
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-UEGURBBW.js";
|
|
16
16
|
import {
|
|
17
17
|
CLAIM_KEY_SOURCES,
|
|
18
18
|
CLAIM_KEY_STATUSES,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
resolveEmbeddingModel,
|
|
42
42
|
resolveModel,
|
|
43
43
|
runUnifiedRecall
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-FMQTRTWE.js";
|
|
45
45
|
import {
|
|
46
46
|
recall
|
|
47
47
|
} from "./chunk-5LADPJ4C.js";
|
|
@@ -37,8 +37,8 @@ function readOptionalTrimmedString(value) {
|
|
|
37
37
|
function readOptionalFiniteNumber(value) {
|
|
38
38
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
39
39
|
}
|
|
40
|
-
function pushIssue(issues,
|
|
41
|
-
issues.push({ path:
|
|
40
|
+
function pushIssue(issues, path5, message) {
|
|
41
|
+
issues.push({ path: path5, message });
|
|
42
42
|
}
|
|
43
43
|
function pushUnexpectedFields(value, allowedKeys, basePath, issues) {
|
|
44
44
|
for (const key of Object.keys(value)) {
|
|
@@ -48,68 +48,68 @@ function pushUnexpectedFields(value, allowedKeys, basePath, issues) {
|
|
|
48
48
|
pushIssue(issues, joinPath(basePath, key), "Unexpected field.");
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
function parseRequiredTrimmedString(value,
|
|
51
|
+
function parseRequiredTrimmedString(value, path5, issues, message = "Expected a non-empty string.") {
|
|
52
52
|
if (typeof value !== "string") {
|
|
53
|
-
pushIssue(issues,
|
|
53
|
+
pushIssue(issues, path5, message);
|
|
54
54
|
return void 0;
|
|
55
55
|
}
|
|
56
56
|
const normalized = value.trim();
|
|
57
57
|
if (normalized.length === 0) {
|
|
58
|
-
pushIssue(issues,
|
|
58
|
+
pushIssue(issues, path5, message);
|
|
59
59
|
return void 0;
|
|
60
60
|
}
|
|
61
61
|
return normalized;
|
|
62
62
|
}
|
|
63
|
-
function parseOptionalTrimmedString(value,
|
|
63
|
+
function parseOptionalTrimmedString(value, path5, issues, typeMessage = "Expected a string.", emptyMessage = "Expected a non-empty string.") {
|
|
64
64
|
if (value === void 0) {
|
|
65
65
|
return void 0;
|
|
66
66
|
}
|
|
67
67
|
if (typeof value !== "string") {
|
|
68
|
-
pushIssue(issues,
|
|
68
|
+
pushIssue(issues, path5, typeMessage);
|
|
69
69
|
return void 0;
|
|
70
70
|
}
|
|
71
71
|
const normalized = value.trim();
|
|
72
72
|
if (normalized.length === 0) {
|
|
73
|
-
pushIssue(issues,
|
|
73
|
+
pushIssue(issues, path5, emptyMessage);
|
|
74
74
|
return void 0;
|
|
75
75
|
}
|
|
76
76
|
return normalized;
|
|
77
77
|
}
|
|
78
|
-
function parseOptionalBoolean(value,
|
|
78
|
+
function parseOptionalBoolean(value, path5, issues, message = "Expected a boolean.") {
|
|
79
79
|
if (value === void 0) {
|
|
80
80
|
return void 0;
|
|
81
81
|
}
|
|
82
82
|
if (typeof value !== "boolean") {
|
|
83
|
-
pushIssue(issues,
|
|
83
|
+
pushIssue(issues, path5, message);
|
|
84
84
|
return void 0;
|
|
85
85
|
}
|
|
86
86
|
return value;
|
|
87
87
|
}
|
|
88
|
-
function parseOptionalIntegerInRange(value,
|
|
88
|
+
function parseOptionalIntegerInRange(value, path5, issues, bounds) {
|
|
89
89
|
if (value === void 0) {
|
|
90
90
|
return void 0;
|
|
91
91
|
}
|
|
92
92
|
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) {
|
|
93
|
-
pushIssue(issues,
|
|
93
|
+
pushIssue(issues, path5, integerRangeMessage(bounds));
|
|
94
94
|
return void 0;
|
|
95
95
|
}
|
|
96
96
|
if (bounds.min !== void 0 && value < bounds.min) {
|
|
97
|
-
pushIssue(issues,
|
|
97
|
+
pushIssue(issues, path5, integerRangeMessage(bounds));
|
|
98
98
|
return void 0;
|
|
99
99
|
}
|
|
100
100
|
if (bounds.max !== void 0 && value > bounds.max) {
|
|
101
|
-
pushIssue(issues,
|
|
101
|
+
pushIssue(issues, path5, integerRangeMessage(bounds));
|
|
102
102
|
return void 0;
|
|
103
103
|
}
|
|
104
104
|
return value;
|
|
105
105
|
}
|
|
106
|
-
function parseOptionalTimestampString(value,
|
|
107
|
-
const timestamp = parseOptionalTrimmedString(value,
|
|
106
|
+
function parseOptionalTimestampString(value, path5, issues, message = "Expected a valid timestamp string.") {
|
|
107
|
+
const timestamp = parseOptionalTrimmedString(value, path5, issues);
|
|
108
108
|
if (timestamp === void 0) {
|
|
109
109
|
return void 0;
|
|
110
110
|
}
|
|
111
111
|
if (Number.isNaN(Date.parse(timestamp))) {
|
|
112
|
-
pushIssue(issues,
|
|
112
|
+
pushIssue(issues, path5, message);
|
|
113
113
|
return void 0;
|
|
114
114
|
}
|
|
115
115
|
return timestamp;
|
|
@@ -142,8 +142,7 @@ function integerRangeMessage(bounds) {
|
|
|
142
142
|
// src/config.ts
|
|
143
143
|
import fs from "fs";
|
|
144
144
|
import os from "os";
|
|
145
|
-
import
|
|
146
|
-
import { fileURLToPath } from "url";
|
|
145
|
+
import path2 from "path";
|
|
147
146
|
|
|
148
147
|
// src/app/features/types.ts
|
|
149
148
|
var AGENR_FEATURE_FLAG_KEYS = ["workingMemory", "sessionTreeLineage", "sessionTreeCompaction", "goalContinuation"];
|
|
@@ -155,7 +154,7 @@ var DEFAULT_AGENR_FEATURE_FLAGS = {
|
|
|
155
154
|
};
|
|
156
155
|
|
|
157
156
|
// src/adapters/config/parse-feature-flags.ts
|
|
158
|
-
function parseFeatureFlags(value,
|
|
157
|
+
function parseFeatureFlags(value, path5, issues) {
|
|
159
158
|
const defaults = DEFAULT_AGENR_FEATURE_FLAGS;
|
|
160
159
|
if (value === void 0) {
|
|
161
160
|
return {
|
|
@@ -163,17 +162,17 @@ function parseFeatureFlags(value, path4, issues) {
|
|
|
163
162
|
};
|
|
164
163
|
}
|
|
165
164
|
if (!isRecord(value)) {
|
|
166
|
-
pushIssue(issues,
|
|
165
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
167
166
|
return {
|
|
168
167
|
resolved: { ...defaults }
|
|
169
168
|
};
|
|
170
169
|
}
|
|
171
170
|
const startIndex = issues.length;
|
|
172
|
-
pushUnexpectedFields(value, new Set(AGENR_FEATURE_FLAG_KEYS),
|
|
173
|
-
const workingMemory = parseOptionalBoolean(value.workingMemory, `${
|
|
174
|
-
const sessionTreeLineage = parseOptionalBoolean(value.sessionTreeLineage, `${
|
|
175
|
-
const sessionTreeCompaction = parseOptionalBoolean(value.sessionTreeCompaction, `${
|
|
176
|
-
const goalContinuation = parseOptionalBoolean(value.goalContinuation, `${
|
|
171
|
+
pushUnexpectedFields(value, new Set(AGENR_FEATURE_FLAG_KEYS), path5, issues);
|
|
172
|
+
const workingMemory = parseOptionalBoolean(value.workingMemory, `${path5}.workingMemory`, issues);
|
|
173
|
+
const sessionTreeLineage = parseOptionalBoolean(value.sessionTreeLineage, `${path5}.sessionTreeLineage`, issues);
|
|
174
|
+
const sessionTreeCompaction = parseOptionalBoolean(value.sessionTreeCompaction, `${path5}.sessionTreeCompaction`, issues);
|
|
175
|
+
const goalContinuation = parseOptionalBoolean(value.goalContinuation, `${path5}.goalContinuation`, issues);
|
|
177
176
|
if (issues.length > startIndex) {
|
|
178
177
|
return {
|
|
179
178
|
resolved: { ...defaults }
|
|
@@ -464,41 +463,41 @@ function pushTopLevelIssues(value, issues) {
|
|
|
464
463
|
pushIssue(issues, "embeddingApiKey", "Removed field. Move this value to credentials.openaiApiKey, then delete embeddingApiKey.");
|
|
465
464
|
}
|
|
466
465
|
}
|
|
467
|
-
function parseAuth(value,
|
|
468
|
-
const normalized = parseOptionalTrimmedString(value,
|
|
466
|
+
function parseAuth(value, path5, issues) {
|
|
467
|
+
const normalized = parseOptionalTrimmedString(value, path5, issues);
|
|
469
468
|
if (!normalized) {
|
|
470
469
|
return void 0;
|
|
471
470
|
}
|
|
472
471
|
if (!isAgenrAuthMethod(normalized)) {
|
|
473
|
-
pushIssue(issues,
|
|
472
|
+
pushIssue(issues, path5, "Expected a supported auth method.");
|
|
474
473
|
return void 0;
|
|
475
474
|
}
|
|
476
475
|
return normalized;
|
|
477
476
|
}
|
|
478
|
-
function parseProvider(value,
|
|
479
|
-
const normalized = parseOptionalTrimmedString(value,
|
|
477
|
+
function parseProvider(value, path5, issues) {
|
|
478
|
+
const normalized = parseOptionalTrimmedString(value, path5, issues);
|
|
480
479
|
if (!normalized) {
|
|
481
480
|
return void 0;
|
|
482
481
|
}
|
|
483
482
|
if (!isAgenrProvider(normalized)) {
|
|
484
|
-
pushIssue(issues,
|
|
483
|
+
pushIssue(issues, path5, "Expected a supported provider.");
|
|
485
484
|
return void 0;
|
|
486
485
|
}
|
|
487
486
|
return normalized;
|
|
488
487
|
}
|
|
489
|
-
function parseCredentials(value,
|
|
488
|
+
function parseCredentials(value, path5, issues) {
|
|
490
489
|
if (value === void 0) {
|
|
491
490
|
return void 0;
|
|
492
491
|
}
|
|
493
492
|
if (!isRecord(value)) {
|
|
494
|
-
pushIssue(issues,
|
|
493
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
495
494
|
return void 0;
|
|
496
495
|
}
|
|
497
496
|
const startIndex = issues.length;
|
|
498
|
-
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["openaiApiKey", "anthropicApiKey", "anthropicOauthToken"]),
|
|
499
|
-
const openaiApiKey = parseOptionalTrimmedString(value.openaiApiKey, `${
|
|
500
|
-
const anthropicApiKey = parseOptionalTrimmedString(value.anthropicApiKey, `${
|
|
501
|
-
const anthropicOauthToken = parseOptionalTrimmedString(value.anthropicOauthToken, `${
|
|
497
|
+
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["openaiApiKey", "anthropicApiKey", "anthropicOauthToken"]), path5, issues);
|
|
498
|
+
const openaiApiKey = parseOptionalTrimmedString(value.openaiApiKey, `${path5}.openaiApiKey`, issues);
|
|
499
|
+
const anthropicApiKey = parseOptionalTrimmedString(value.anthropicApiKey, `${path5}.anthropicApiKey`, issues);
|
|
500
|
+
const anthropicOauthToken = parseOptionalTrimmedString(value.anthropicOauthToken, `${path5}.anthropicOauthToken`, issues);
|
|
502
501
|
if (issues.length > startIndex) {
|
|
503
502
|
return void 0;
|
|
504
503
|
}
|
|
@@ -509,20 +508,20 @@ function parseCredentials(value, path4, issues) {
|
|
|
509
508
|
};
|
|
510
509
|
return hasStoredCredentials(credentials) ? credentials : void 0;
|
|
511
510
|
}
|
|
512
|
-
function parseModelConfig(value,
|
|
511
|
+
function parseModelConfig(value, path5, issues) {
|
|
513
512
|
if (value === void 0) {
|
|
514
513
|
return void 0;
|
|
515
514
|
}
|
|
516
515
|
if (!isRecord(value)) {
|
|
517
|
-
pushIssue(issues,
|
|
516
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
518
517
|
return void 0;
|
|
519
518
|
}
|
|
520
519
|
const startIndex = issues.length;
|
|
521
|
-
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["provider", "model"]),
|
|
522
|
-
const provider = parseProvider(value.provider, `${
|
|
523
|
-
const model = parseOptionalTrimmedString(value.model, `${
|
|
520
|
+
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["provider", "model"]), path5, issues);
|
|
521
|
+
const provider = parseProvider(value.provider, `${path5}.provider`, issues);
|
|
522
|
+
const model = parseOptionalTrimmedString(value.model, `${path5}.model`, issues);
|
|
524
523
|
if (!provider && !model) {
|
|
525
|
-
pushIssue(issues,
|
|
524
|
+
pushIssue(issues, path5, "Expected at least one of provider or model.");
|
|
526
525
|
}
|
|
527
526
|
if (issues.length > startIndex) {
|
|
528
527
|
return void 0;
|
|
@@ -532,7 +531,7 @@ function parseModelConfig(value, path4, issues) {
|
|
|
532
531
|
...model ? { model } : {}
|
|
533
532
|
};
|
|
534
533
|
}
|
|
535
|
-
function parseClaimExtractionConfig(value,
|
|
534
|
+
function parseClaimExtractionConfig(value, path5, issues) {
|
|
536
535
|
const defaults = createDefaultClaimExtractionConfig();
|
|
537
536
|
if (value === void 0) {
|
|
538
537
|
return {
|
|
@@ -540,20 +539,20 @@ function parseClaimExtractionConfig(value, path4, issues) {
|
|
|
540
539
|
};
|
|
541
540
|
}
|
|
542
541
|
if (!isRecord(value)) {
|
|
543
|
-
pushIssue(issues,
|
|
542
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
544
543
|
return {
|
|
545
544
|
resolved: defaults
|
|
546
545
|
};
|
|
547
546
|
}
|
|
548
547
|
const startIndex = issues.length;
|
|
549
|
-
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled", "confidenceThreshold", "eligibleTypes", "concurrency", "model"]),
|
|
550
|
-
const enabled = parseOptionalBoolean(value.enabled, `${
|
|
551
|
-
const confidenceThreshold = parseOptionalUnitInterval(value.confidenceThreshold, `${
|
|
552
|
-
const eligibleTypes = parseEligibleTypes(value.eligibleTypes, `${
|
|
553
|
-
const concurrency = parseOptionalIntegerInRange(value.concurrency, `${
|
|
548
|
+
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["enabled", "confidenceThreshold", "eligibleTypes", "concurrency", "model"]), path5, issues);
|
|
549
|
+
const enabled = parseOptionalBoolean(value.enabled, `${path5}.enabled`, issues);
|
|
550
|
+
const confidenceThreshold = parseOptionalUnitInterval(value.confidenceThreshold, `${path5}.confidenceThreshold`, issues);
|
|
551
|
+
const eligibleTypes = parseEligibleTypes(value.eligibleTypes, `${path5}.eligibleTypes`, issues);
|
|
552
|
+
const concurrency = parseOptionalIntegerInRange(value.concurrency, `${path5}.concurrency`, issues, {
|
|
554
553
|
min: 1
|
|
555
554
|
});
|
|
556
|
-
const model = parseModelConfig(value.model, `${
|
|
555
|
+
const model = parseModelConfig(value.model, `${path5}.model`, issues);
|
|
557
556
|
if (issues.length > startIndex) {
|
|
558
557
|
return {
|
|
559
558
|
resolved: defaults
|
|
@@ -577,7 +576,7 @@ function parseClaimExtractionConfig(value, path4, issues) {
|
|
|
577
576
|
}
|
|
578
577
|
};
|
|
579
578
|
}
|
|
580
|
-
function parseSurgeonConfig(value,
|
|
579
|
+
function parseSurgeonConfig(value, path5, issues) {
|
|
581
580
|
const defaults = createDefaultSurgeonConfig();
|
|
582
581
|
if (value === void 0) {
|
|
583
582
|
return {
|
|
@@ -585,19 +584,19 @@ function parseSurgeonConfig(value, path4, issues) {
|
|
|
585
584
|
};
|
|
586
585
|
}
|
|
587
586
|
if (!isRecord(value)) {
|
|
588
|
-
pushIssue(issues,
|
|
587
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
589
588
|
return {
|
|
590
589
|
resolved: defaults
|
|
591
590
|
};
|
|
592
591
|
}
|
|
593
592
|
const startIndex = issues.length;
|
|
594
|
-
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["model", "costCap", "dailyCostCap", "contextLimit", "customInstructions", "passes"]),
|
|
595
|
-
const model = parseModelConfig(value.model, `${
|
|
596
|
-
const costCap = parseOptionalPositiveNumber(value.costCap, `${
|
|
597
|
-
const dailyCostCap = parseOptionalNonNegativeNumber(value.dailyCostCap, `${
|
|
598
|
-
const contextLimit = parseOptionalIntegerInRange(value.contextLimit, `${
|
|
599
|
-
const customInstructions = parseOptionalTrimmedString(value.customInstructions, `${
|
|
600
|
-
const retirement = parseRetirementPassConfig(value.passes, `${
|
|
593
|
+
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["model", "costCap", "dailyCostCap", "contextLimit", "customInstructions", "passes"]), path5, issues);
|
|
594
|
+
const model = parseModelConfig(value.model, `${path5}.model`, issues);
|
|
595
|
+
const costCap = parseOptionalPositiveNumber(value.costCap, `${path5}.costCap`, issues);
|
|
596
|
+
const dailyCostCap = parseOptionalNonNegativeNumber(value.dailyCostCap, `${path5}.dailyCostCap`, issues);
|
|
597
|
+
const contextLimit = parseOptionalIntegerInRange(value.contextLimit, `${path5}.contextLimit`, issues, { min: 0 });
|
|
598
|
+
const customInstructions = parseOptionalTrimmedString(value.customInstructions, `${path5}.customInstructions`, issues);
|
|
599
|
+
const retirement = parseRetirementPassConfig(value.passes, `${path5}.passes`, issues);
|
|
601
600
|
if (issues.length > startIndex) {
|
|
602
601
|
return {
|
|
603
602
|
resolved: defaults
|
|
@@ -629,7 +628,7 @@ function parseSurgeonConfig(value, path4, issues) {
|
|
|
629
628
|
}
|
|
630
629
|
};
|
|
631
630
|
}
|
|
632
|
-
function parseRetirementPassConfig(value,
|
|
631
|
+
function parseRetirementPassConfig(value, path5, issues) {
|
|
633
632
|
const defaults = createDefaultRetirementPassConfig();
|
|
634
633
|
if (value === void 0) {
|
|
635
634
|
return {
|
|
@@ -637,36 +636,36 @@ function parseRetirementPassConfig(value, path4, issues) {
|
|
|
637
636
|
};
|
|
638
637
|
}
|
|
639
638
|
if (!isRecord(value)) {
|
|
640
|
-
pushIssue(issues,
|
|
639
|
+
pushIssue(issues, path5, "Expected an object.");
|
|
641
640
|
return {
|
|
642
641
|
resolved: defaults
|
|
643
642
|
};
|
|
644
643
|
}
|
|
645
644
|
const startIndex = issues.length;
|
|
646
|
-
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["retirement"]),
|
|
645
|
+
pushUnexpectedFields(value, /* @__PURE__ */ new Set(["retirement"]), path5, issues);
|
|
647
646
|
const retirement = value.retirement;
|
|
648
647
|
if (retirement === void 0) {
|
|
649
648
|
if (issues.length === startIndex) {
|
|
650
|
-
pushIssue(issues,
|
|
649
|
+
pushIssue(issues, path5, "Expected a retirement config when passes is provided.");
|
|
651
650
|
}
|
|
652
651
|
return {
|
|
653
652
|
resolved: defaults
|
|
654
653
|
};
|
|
655
654
|
}
|
|
656
655
|
if (!isRecord(retirement)) {
|
|
657
|
-
pushIssue(issues, `${
|
|
656
|
+
pushIssue(issues, `${path5}.retirement`, "Expected an object.");
|
|
658
657
|
return {
|
|
659
658
|
resolved: defaults
|
|
660
659
|
};
|
|
661
660
|
}
|
|
662
|
-
pushUnexpectedFields(retirement, /* @__PURE__ */ new Set(["protectRecalledDays", "protectMinImportance", "skipRecentlyEvaluatedDays"]), `${
|
|
663
|
-
const protectRecalledDays = parseOptionalIntegerInRange(retirement.protectRecalledDays, `${
|
|
661
|
+
pushUnexpectedFields(retirement, /* @__PURE__ */ new Set(["protectRecalledDays", "protectMinImportance", "skipRecentlyEvaluatedDays"]), `${path5}.retirement`, issues);
|
|
662
|
+
const protectRecalledDays = parseOptionalIntegerInRange(retirement.protectRecalledDays, `${path5}.retirement.protectRecalledDays`, issues, {
|
|
664
663
|
min: 0
|
|
665
664
|
});
|
|
666
|
-
const protectMinImportance = parseOptionalIntegerInRange(retirement.protectMinImportance, `${
|
|
665
|
+
const protectMinImportance = parseOptionalIntegerInRange(retirement.protectMinImportance, `${path5}.retirement.protectMinImportance`, issues, {
|
|
667
666
|
min: 0
|
|
668
667
|
});
|
|
669
|
-
const skipRecentlyEvaluatedDays = parseOptionalIntegerInRange(retirement.skipRecentlyEvaluatedDays, `${
|
|
668
|
+
const skipRecentlyEvaluatedDays = parseOptionalIntegerInRange(retirement.skipRecentlyEvaluatedDays, `${path5}.retirement.skipRecentlyEvaluatedDays`, issues, {
|
|
670
669
|
min: 0
|
|
671
670
|
});
|
|
672
671
|
if (issues.length > startIndex) {
|
|
@@ -688,54 +687,54 @@ function parseRetirementPassConfig(value, path4, issues) {
|
|
|
688
687
|
}
|
|
689
688
|
};
|
|
690
689
|
}
|
|
691
|
-
function parseOptionalUnitInterval(value,
|
|
690
|
+
function parseOptionalUnitInterval(value, path5, issues) {
|
|
692
691
|
if (value === void 0) {
|
|
693
692
|
return void 0;
|
|
694
693
|
}
|
|
695
694
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 1) {
|
|
696
|
-
pushIssue(issues,
|
|
695
|
+
pushIssue(issues, path5, "Expected a number from 0 to 1.");
|
|
697
696
|
return void 0;
|
|
698
697
|
}
|
|
699
698
|
return value;
|
|
700
699
|
}
|
|
701
|
-
function parseOptionalPositiveNumber(value,
|
|
700
|
+
function parseOptionalPositiveNumber(value, path5, issues) {
|
|
702
701
|
if (value === void 0) {
|
|
703
702
|
return void 0;
|
|
704
703
|
}
|
|
705
704
|
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
706
|
-
pushIssue(issues,
|
|
705
|
+
pushIssue(issues, path5, "Expected a positive number.");
|
|
707
706
|
return void 0;
|
|
708
707
|
}
|
|
709
708
|
return value;
|
|
710
709
|
}
|
|
711
|
-
function parseOptionalNonNegativeNumber(value,
|
|
710
|
+
function parseOptionalNonNegativeNumber(value, path5, issues) {
|
|
712
711
|
if (value === void 0) {
|
|
713
712
|
return void 0;
|
|
714
713
|
}
|
|
715
714
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
716
|
-
pushIssue(issues,
|
|
715
|
+
pushIssue(issues, path5, "Expected a non-negative number.");
|
|
717
716
|
return void 0;
|
|
718
717
|
}
|
|
719
718
|
return value;
|
|
720
719
|
}
|
|
721
|
-
function parseEligibleTypes(value,
|
|
720
|
+
function parseEligibleTypes(value, path5, issues) {
|
|
722
721
|
if (value === void 0) {
|
|
723
722
|
return void 0;
|
|
724
723
|
}
|
|
725
724
|
if (!Array.isArray(value)) {
|
|
726
|
-
pushIssue(issues,
|
|
725
|
+
pushIssue(issues, path5, "Expected an array of entry types.");
|
|
727
726
|
return void 0;
|
|
728
727
|
}
|
|
729
728
|
const normalized = [];
|
|
730
729
|
const seen = /* @__PURE__ */ new Set();
|
|
731
730
|
for (const [index, item] of value.entries()) {
|
|
732
731
|
if (typeof item !== "string") {
|
|
733
|
-
pushIssue(issues, `${
|
|
732
|
+
pushIssue(issues, `${path5}.${index}`, "Expected a supported entry type.");
|
|
734
733
|
continue;
|
|
735
734
|
}
|
|
736
735
|
const trimmed = item.trim();
|
|
737
736
|
if (!isEntryType(trimmed)) {
|
|
738
|
-
pushIssue(issues, `${
|
|
737
|
+
pushIssue(issues, `${path5}.${index}`, "Expected a supported entry type.");
|
|
739
738
|
continue;
|
|
740
739
|
}
|
|
741
740
|
if (!seen.has(trimmed)) {
|
|
@@ -744,7 +743,7 @@ function parseEligibleTypes(value, path4, issues) {
|
|
|
744
743
|
}
|
|
745
744
|
}
|
|
746
745
|
if (normalized.length === 0) {
|
|
747
|
-
pushIssue(issues,
|
|
746
|
+
pushIssue(issues, path5, "Expected at least one supported entry type.");
|
|
748
747
|
return void 0;
|
|
749
748
|
}
|
|
750
749
|
return normalized;
|
|
@@ -818,8 +817,53 @@ function toSurgeonInput(value) {
|
|
|
818
817
|
return hasSurgeonInput(input) ? input : void 0;
|
|
819
818
|
}
|
|
820
819
|
|
|
820
|
+
// src/filesystem-path.ts
|
|
821
|
+
import path from "path";
|
|
822
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
823
|
+
function toAbsoluteFileUrl(filePath) {
|
|
824
|
+
return pathToFileURL(path.resolve(filePath)).href;
|
|
825
|
+
}
|
|
826
|
+
function resolveLocalFilesystemPath(targetPath) {
|
|
827
|
+
const trimmedPath = targetPath.trim();
|
|
828
|
+
if (trimmedPath.length === 0 || trimmedPath === ":memory:" || isInMemoryFileUrl(trimmedPath)) {
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
if (trimmedPath.startsWith("file:")) {
|
|
832
|
+
if (isAbsoluteFileUrl(trimmedPath)) {
|
|
833
|
+
try {
|
|
834
|
+
return fileURLToPath(trimmedPath);
|
|
835
|
+
} catch {
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
const relativePath = decodeRelativeFileUrlPath(trimmedPath);
|
|
840
|
+
return relativePath ? path.resolve(relativePath) : null;
|
|
841
|
+
}
|
|
842
|
+
return path.resolve(trimmedPath);
|
|
843
|
+
}
|
|
844
|
+
function resolveConfigFilesystemPath(targetPath) {
|
|
845
|
+
return resolveLocalFilesystemPath(targetPath) ?? targetPath;
|
|
846
|
+
}
|
|
847
|
+
function isAbsoluteFileUrl(targetPath) {
|
|
848
|
+
return /^file:(?:\/|[A-Za-z]:[\\/])/u.test(targetPath);
|
|
849
|
+
}
|
|
850
|
+
function isInMemoryFileUrl(targetPath) {
|
|
851
|
+
return targetPath === "file::memory:" || targetPath.startsWith("file::memory:?");
|
|
852
|
+
}
|
|
853
|
+
function decodeRelativeFileUrlPath(targetPath) {
|
|
854
|
+
const rawPath = targetPath.slice("file:".length).split(/[?#]/u, 1)[0]?.trim();
|
|
855
|
+
if (!rawPath) {
|
|
856
|
+
return null;
|
|
857
|
+
}
|
|
858
|
+
try {
|
|
859
|
+
return decodeURIComponent(rawPath);
|
|
860
|
+
} catch {
|
|
861
|
+
return rawPath;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
821
865
|
// src/config.ts
|
|
822
|
-
var DEFAULT_CONFIG_DIR =
|
|
866
|
+
var DEFAULT_CONFIG_DIR = path2.join(os.homedir(), ".agenr");
|
|
823
867
|
var DEFAULT_DB_NAME = "knowledge.db";
|
|
824
868
|
var CONFIG_DIR_MODE = 448;
|
|
825
869
|
var CONFIG_FILE_MODE = 384;
|
|
@@ -839,7 +883,7 @@ function resolveConfigPath(options = {}) {
|
|
|
839
883
|
if (adjacentConfigPath) {
|
|
840
884
|
return adjacentConfigPath;
|
|
841
885
|
}
|
|
842
|
-
return
|
|
886
|
+
return path2.join(resolveConfigDir(), "config.json");
|
|
843
887
|
}
|
|
844
888
|
function resolveDbPath(config) {
|
|
845
889
|
return normalizeOptionalString(process.env.AGENR_DB_PATH) ?? normalizeOptionalString(config?.dbPath) ?? resolvePersistedDefaultDbPath();
|
|
@@ -880,7 +924,7 @@ function resolveClaimExtractionConfig(config) {
|
|
|
880
924
|
};
|
|
881
925
|
}
|
|
882
926
|
function readConfig(options = {}) {
|
|
883
|
-
const configPath =
|
|
927
|
+
const configPath = resolveConfigFilesystemPath(resolveConfigPath(options));
|
|
884
928
|
const defaultDbPath = resolveReadDefaultDbPath(options);
|
|
885
929
|
if (!fs.existsSync(configPath)) {
|
|
886
930
|
const parsed2 = parseAgenrConfig(void 0, { defaultDbPath });
|
|
@@ -906,11 +950,11 @@ function readConfig(options = {}) {
|
|
|
906
950
|
return parsed.value;
|
|
907
951
|
}
|
|
908
952
|
function configFileExists(options = {}) {
|
|
909
|
-
return fs.existsSync(
|
|
953
|
+
return fs.existsSync(resolveConfigFilesystemPath(resolveConfigPath(options)));
|
|
910
954
|
}
|
|
911
955
|
function writeConfig(config, options = {}) {
|
|
912
|
-
const configPath =
|
|
913
|
-
const configDir =
|
|
956
|
+
const configPath = resolveConfigFilesystemPath(resolveConfigPath(options));
|
|
957
|
+
const configDir = path2.dirname(configPath);
|
|
914
958
|
const canonical = canonicalizeAgenrConfigInput(config, {
|
|
915
959
|
defaultDbPath: resolvePersistedDefaultDbPath()
|
|
916
960
|
});
|
|
@@ -938,30 +982,17 @@ function resolveAdjacentConfigPath(dbPath) {
|
|
|
938
982
|
return void 0;
|
|
939
983
|
}
|
|
940
984
|
if (normalizedDbPath.startsWith("file:")) {
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
} catch {
|
|
944
|
-
return void 0;
|
|
945
|
-
}
|
|
985
|
+
const filePath = resolveLocalFilesystemPath(normalizedDbPath);
|
|
986
|
+
return filePath ? path2.join(path2.dirname(filePath), "config.json") : void 0;
|
|
946
987
|
}
|
|
947
|
-
return
|
|
988
|
+
return path2.join(path2.dirname(normalizedDbPath), "config.json");
|
|
948
989
|
}
|
|
949
990
|
function normalizeOptionalString(value) {
|
|
950
991
|
const normalized = value?.trim();
|
|
951
992
|
return normalized && normalized.length > 0 ? normalized : void 0;
|
|
952
993
|
}
|
|
953
|
-
function resolveFilesystemPath(targetPath) {
|
|
954
|
-
if (!targetPath.startsWith("file:")) {
|
|
955
|
-
return targetPath;
|
|
956
|
-
}
|
|
957
|
-
try {
|
|
958
|
-
return fileURLToPath(targetPath);
|
|
959
|
-
} catch {
|
|
960
|
-
return targetPath;
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
994
|
function resolvePersistedDefaultDbPath() {
|
|
964
|
-
return
|
|
995
|
+
return path2.join(resolveConfigDir(), DEFAULT_DB_NAME);
|
|
965
996
|
}
|
|
966
997
|
function resolveReadDefaultDbPath(options) {
|
|
967
998
|
return normalizeOptionalString(process.env.AGENR_DB_PATH) ?? normalizeOptionalString(options.dbPath) ?? resolvePersistedDefaultDbPath();
|
|
@@ -1151,7 +1182,7 @@ async function sleep(durationMs) {
|
|
|
1151
1182
|
import { createHash } from "crypto";
|
|
1152
1183
|
import fs2 from "fs";
|
|
1153
1184
|
import os2 from "os";
|
|
1154
|
-
import
|
|
1185
|
+
import path3 from "path";
|
|
1155
1186
|
import { createRequire } from "module";
|
|
1156
1187
|
import { completeSimple, getEnvApiKey, getModel } from "@earendil-works/pi-ai";
|
|
1157
1188
|
var DEFAULT_REASONING = "medium";
|
|
@@ -1330,33 +1361,38 @@ function safeReadJson(filePath) {
|
|
|
1330
1361
|
}
|
|
1331
1362
|
}
|
|
1332
1363
|
function resolveHomeDir(env) {
|
|
1333
|
-
const home = normalizeOptionalString2(env.HOME);
|
|
1364
|
+
const home = normalizeOptionalString2(env.HOME) ?? normalizeOptionalString2(env.USERPROFILE) ?? resolveWindowsHomeFromParts(env);
|
|
1334
1365
|
return home ? resolveUserPath(home) : os2.homedir();
|
|
1335
1366
|
}
|
|
1336
1367
|
function resolveCodexHome(env) {
|
|
1337
1368
|
const configured = normalizeOptionalString2(env.CODEX_HOME) ?? "~/.codex";
|
|
1338
|
-
const resolved = resolveUserPath(configured);
|
|
1369
|
+
const resolved = resolveUserPath(configured, resolveHomeDir(env));
|
|
1339
1370
|
try {
|
|
1340
1371
|
return fs2.realpathSync.native(resolved);
|
|
1341
1372
|
} catch {
|
|
1342
1373
|
return resolved;
|
|
1343
1374
|
}
|
|
1344
1375
|
}
|
|
1345
|
-
function resolveUserPath(value) {
|
|
1376
|
+
function resolveUserPath(value, homeDir = os2.homedir()) {
|
|
1346
1377
|
const trimmed = value.trim();
|
|
1347
1378
|
if (trimmed === "~") {
|
|
1348
|
-
return
|
|
1379
|
+
return homeDir;
|
|
1349
1380
|
}
|
|
1350
1381
|
if (trimmed.startsWith("~/")) {
|
|
1351
|
-
return
|
|
1382
|
+
return path3.join(homeDir, trimmed.slice(2));
|
|
1352
1383
|
}
|
|
1353
1384
|
if (trimmed.startsWith("~\\")) {
|
|
1354
|
-
return
|
|
1385
|
+
return path3.join(homeDir, trimmed.slice(2));
|
|
1355
1386
|
}
|
|
1356
|
-
return
|
|
1387
|
+
return path3.resolve(trimmed);
|
|
1388
|
+
}
|
|
1389
|
+
function resolveWindowsHomeFromParts(env) {
|
|
1390
|
+
const drive = normalizeOptionalString2(env.HOMEDRIVE);
|
|
1391
|
+
const homePath = normalizeOptionalString2(env.HOMEPATH);
|
|
1392
|
+
return drive && homePath ? `${drive}${homePath}` : void 0;
|
|
1357
1393
|
}
|
|
1358
1394
|
function parseCodexFromFile(env) {
|
|
1359
|
-
const authPath =
|
|
1395
|
+
const authPath = path3.join(resolveCodexHome(env), "auth.json");
|
|
1360
1396
|
const parsed = safeReadJson(authPath);
|
|
1361
1397
|
if (!parsed || typeof parsed !== "object") {
|
|
1362
1398
|
return null;
|
|
@@ -1419,7 +1455,7 @@ function parseClaudeCredentialRecord(parsed, source) {
|
|
|
1419
1455
|
}
|
|
1420
1456
|
function parseClaudeFromFiles(env) {
|
|
1421
1457
|
const homeDir = resolveHomeDir(env);
|
|
1422
|
-
const candidates = [
|
|
1458
|
+
const candidates = [path3.join(homeDir, ".claude", ".credentials.json"), path3.join(homeDir, ".claude", "credentials.json")];
|
|
1423
1459
|
for (const candidate of candidates) {
|
|
1424
1460
|
const parsed = safeReadJson(candidate);
|
|
1425
1461
|
const resolved = parseClaudeCredentialRecord(parsed, `file:${candidate}`);
|
|
@@ -1747,7 +1783,7 @@ async function sleep2(durationMs) {
|
|
|
1747
1783
|
|
|
1748
1784
|
// src/adapters/db/client.ts
|
|
1749
1785
|
import fs3 from "fs/promises";
|
|
1750
|
-
import
|
|
1786
|
+
import path4 from "path";
|
|
1751
1787
|
import { createClient } from "@libsql/client";
|
|
1752
1788
|
|
|
1753
1789
|
// src/adapters/db/episode-queries.ts
|
|
@@ -3192,14 +3228,14 @@ function normalizeProcedureSources(value, label, filePath, options = {}) {
|
|
|
3192
3228
|
function normalizeProcedureSource(record, label, filePath) {
|
|
3193
3229
|
rejectUnexpectedProcedureFields(record, SOURCE_KEYS, label, filePath);
|
|
3194
3230
|
const kind = readProcedureSourceKind(record.kind, `${label}.kind`, filePath, PROCEDURE_SOURCE_KINDS);
|
|
3195
|
-
const
|
|
3231
|
+
const path5 = readOptionalProcedureString(record.path, `${label}.path`, filePath);
|
|
3196
3232
|
const locator = readOptionalProcedureString(record.locator, `${label}.locator`, filePath);
|
|
3197
3233
|
const sourceLabel = readOptionalProcedureString(record.label, `${label}.label`, filePath);
|
|
3198
3234
|
switch (kind) {
|
|
3199
3235
|
case "skill":
|
|
3200
3236
|
case "doc":
|
|
3201
3237
|
case "repo_file":
|
|
3202
|
-
if (!
|
|
3238
|
+
if (!path5) {
|
|
3203
3239
|
throw new Error(`Invalid procedure ${filePath}: ${label}.${kind} sources require a path.`);
|
|
3204
3240
|
}
|
|
3205
3241
|
break;
|
|
@@ -3217,7 +3253,7 @@ function normalizeProcedureSource(record, label, filePath) {
|
|
|
3217
3253
|
}
|
|
3218
3254
|
return {
|
|
3219
3255
|
kind,
|
|
3220
|
-
...
|
|
3256
|
+
...path5 ? { path: path5 } : {},
|
|
3221
3257
|
...locator ? { locator } : {},
|
|
3222
3258
|
...sourceLabel ? { label: sourceLabel } : {}
|
|
3223
3259
|
};
|
|
@@ -5371,9 +5407,9 @@ async function openClient(dbPath) {
|
|
|
5371
5407
|
if (trimmedPath.length === 0) {
|
|
5372
5408
|
throw new Error("Database path must not be empty.");
|
|
5373
5409
|
}
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
await fs3.mkdir(
|
|
5410
|
+
const localDbPath = resolveLocalFilesystemPath(trimmedPath);
|
|
5411
|
+
if (localDbPath) {
|
|
5412
|
+
await fs3.mkdir(path4.dirname(localDbPath), { recursive: true });
|
|
5377
5413
|
}
|
|
5378
5414
|
const client = createClient({ url: resolveClientUrl(trimmedPath) });
|
|
5379
5415
|
await client.execute("PRAGMA foreign_keys = ON");
|
|
@@ -5390,7 +5426,7 @@ function resolveClientUrl(dbPath) {
|
|
|
5390
5426
|
if (dbPath.startsWith("file:")) {
|
|
5391
5427
|
return dbPath;
|
|
5392
5428
|
}
|
|
5393
|
-
return
|
|
5429
|
+
return toAbsoluteFileUrl(dbPath);
|
|
5394
5430
|
}
|
|
5395
5431
|
async function rollbackTransaction(transaction) {
|
|
5396
5432
|
if (transaction.closed) {
|
|
@@ -7909,6 +7945,7 @@ function dedupePreservingOrder2(values) {
|
|
|
7909
7945
|
}
|
|
7910
7946
|
|
|
7911
7947
|
export {
|
|
7948
|
+
resolveLocalFilesystemPath,
|
|
7912
7949
|
ENTRY_TYPES,
|
|
7913
7950
|
EXPIRY_LEVELS,
|
|
7914
7951
|
CLAIM_KEY_STATUSES,
|
|
@@ -15,14 +15,14 @@ import {
|
|
|
15
15
|
parseRecallMode,
|
|
16
16
|
resolveTargetEntry,
|
|
17
17
|
storeEntriesDetailed
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-TMDNFBBC.js";
|
|
19
19
|
import {
|
|
20
20
|
containsAgenrMemoryContext,
|
|
21
21
|
formatInjectionEntryBodyLines,
|
|
22
22
|
formatInjectionEntryHeader,
|
|
23
23
|
stripAgenrMemoryContext,
|
|
24
24
|
wrapAgenrMemoryContext
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-UEGURBBW.js";
|
|
26
26
|
import {
|
|
27
27
|
ENTRY_PREVIEW_MAX_CHARS,
|
|
28
28
|
ENTRY_SELECT_COLUMNS,
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
runUnifiedRecall,
|
|
58
58
|
truncate,
|
|
59
59
|
validateTemporalValidityRange
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-FMQTRTWE.js";
|
|
61
61
|
import {
|
|
62
62
|
recall
|
|
63
63
|
} from "./chunk-5LADPJ4C.js";
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
openClawTranscriptParser,
|
|
10
10
|
parseTuiSessionKey,
|
|
11
11
|
readOpenClawSessionsStore
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ZAX3YSTU.js";
|
|
13
13
|
import {
|
|
14
14
|
applyClaimExtractionResultToEntry,
|
|
15
15
|
backfillEpisodeEmbeddings,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
tokenizeGroundingText,
|
|
34
34
|
validateEntriesWithIndexes,
|
|
35
35
|
validateSupersessionRules
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-TMDNFBBC.js";
|
|
37
37
|
import {
|
|
38
38
|
DEFAULT_CLAIM_EXTRACTION_CONCURRENCY,
|
|
39
39
|
DEFAULT_SURGEON_CONTEXT_LIMIT,
|
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
resolveEmbeddingModel,
|
|
94
94
|
resolveLlmApiKey,
|
|
95
95
|
resolveLlmCredentials,
|
|
96
|
+
resolveLocalFilesystemPath,
|
|
96
97
|
resolveModel,
|
|
97
98
|
retireEntry,
|
|
98
99
|
supersedeEntry,
|
|
@@ -100,7 +101,7 @@ import {
|
|
|
100
101
|
updateEntry,
|
|
101
102
|
validateTemporalValidityRange,
|
|
102
103
|
writeConfig
|
|
103
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-FMQTRTWE.js";
|
|
104
105
|
import {
|
|
105
106
|
compactClaimKey,
|
|
106
107
|
describeClaimKeyNormalizationFailure,
|
|
@@ -168,7 +169,6 @@ function formatLabel(label, value) {
|
|
|
168
169
|
// src/cli/commands/db.ts
|
|
169
170
|
import fs from "fs/promises";
|
|
170
171
|
import path from "path";
|
|
171
|
-
import { fileURLToPath } from "url";
|
|
172
172
|
import * as clack from "@clack/prompts";
|
|
173
173
|
function registerDbCommand(program2) {
|
|
174
174
|
const dbCommand = program2.command("db").description("Database utilities");
|
|
@@ -199,25 +199,11 @@ function registerDbCommand(program2) {
|
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
function resolveResetPath(dbPath) {
|
|
202
|
-
|
|
202
|
+
const trimmedPath = dbPath.trim();
|
|
203
|
+
if (trimmedPath === ":memory:") {
|
|
203
204
|
return { displayPath: dbPath };
|
|
204
205
|
}
|
|
205
|
-
|
|
206
|
-
try {
|
|
207
|
-
const filePath = fileURLToPath(dbPath);
|
|
208
|
-
return {
|
|
209
|
-
deletePath: filePath,
|
|
210
|
-
displayPath: filePath
|
|
211
|
-
};
|
|
212
|
-
} catch {
|
|
213
|
-
const resolvedPath2 = path.resolve(dbPath.slice("file:".length));
|
|
214
|
-
return {
|
|
215
|
-
deletePath: resolvedPath2,
|
|
216
|
-
displayPath: resolvedPath2
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const resolvedPath = path.resolve(dbPath);
|
|
206
|
+
const resolvedPath = resolveLocalFilesystemPath(trimmedPath) ?? path.resolve(trimmedPath);
|
|
221
207
|
return {
|
|
222
208
|
deletePath: resolvedPath,
|
|
223
209
|
displayPath: resolvedPath
|
|
@@ -5135,7 +5121,11 @@ import path11 from "path";
|
|
|
5135
5121
|
var OPENCLAW_PLUGIN_PACKAGE = "@agenr/agenr-plugin";
|
|
5136
5122
|
function execAsync(command, args, options) {
|
|
5137
5123
|
return new Promise((resolve, reject) => {
|
|
5138
|
-
|
|
5124
|
+
const execOptions = {
|
|
5125
|
+
...options,
|
|
5126
|
+
...shouldUseShellForCommand(command) ? { shell: true } : {}
|
|
5127
|
+
};
|
|
5128
|
+
execFile(command, args, execOptions, (error, stdout, stderr) => {
|
|
5139
5129
|
if (error) {
|
|
5140
5130
|
const message = [String(stderr ?? "").trim(), error.message].filter((value) => value.length > 0).join("\n");
|
|
5141
5131
|
reject(new Error(message || error.message));
|
|
@@ -5148,11 +5138,18 @@ function execAsync(command, args, options) {
|
|
|
5148
5138
|
});
|
|
5149
5139
|
});
|
|
5150
5140
|
}
|
|
5141
|
+
function shouldUseShellForCommand(command, platform = process.platform) {
|
|
5142
|
+
if (platform !== "win32") {
|
|
5143
|
+
return false;
|
|
5144
|
+
}
|
|
5145
|
+
const extension = path11.extname(command).toLowerCase();
|
|
5146
|
+
return extension === ".cmd" || extension === ".bat";
|
|
5147
|
+
}
|
|
5151
5148
|
function findBinaryPath(name) {
|
|
5152
5149
|
try {
|
|
5153
5150
|
const lookupCommand = process.platform === "win32" ? "where" : "which";
|
|
5154
5151
|
const output = execFileSync(lookupCommand, [name], { encoding: "utf8" }).trim();
|
|
5155
|
-
const firstLine = output.split(
|
|
5152
|
+
const firstLine = output.split(/\r?\n/u)[0]?.trim();
|
|
5156
5153
|
return firstLine && firstLine.length > 0 ? firstLine : null;
|
|
5157
5154
|
} catch {
|
|
5158
5155
|
return null;
|
|
@@ -14212,10 +14209,10 @@ function readRequiredTrue(value, label, filePath) {
|
|
|
14212
14209
|
// src/app/scenarios/claim-keys/validation/scenario-root.ts
|
|
14213
14210
|
import { existsSync } from "fs";
|
|
14214
14211
|
import path16 from "path";
|
|
14215
|
-
import { fileURLToPath
|
|
14212
|
+
import { fileURLToPath } from "url";
|
|
14216
14213
|
var SCENARIO_ROOT_SEGMENTS = ["tests", "scenarios", "claim-keys"];
|
|
14217
14214
|
function getDefaultClaimKeyScenarioRoot(options = {}) {
|
|
14218
|
-
const moduleDirectory = path16.dirname(
|
|
14215
|
+
const moduleDirectory = path16.dirname(fileURLToPath(options.moduleUrl ?? import.meta.url));
|
|
14219
14216
|
const startDirectories = Array.from(/* @__PURE__ */ new Set([path16.resolve(options.cwd ?? process.cwd()), moduleDirectory]));
|
|
14220
14217
|
for (const startDirectory of startDirectories) {
|
|
14221
14218
|
const discovered = findScenarioRootFrom(startDirectory);
|
|
@@ -15653,7 +15650,7 @@ import { InvalidArgumentError as InvalidArgumentError6, Option as Option5 } from
|
|
|
15653
15650
|
// src/app/surgeon/runtime.ts
|
|
15654
15651
|
import { copyFile, mkdir as mkdir3 } from "fs/promises";
|
|
15655
15652
|
import path21 from "path";
|
|
15656
|
-
import { fileURLToPath as
|
|
15653
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
15657
15654
|
import { getModel as getModel2 } from "@earendil-works/pi-ai";
|
|
15658
15655
|
var DEFAULT_SURGEON_PROVIDER = "openai";
|
|
15659
15656
|
var DEFAULT_SURGEON_MODEL = "gpt-5.4-mini";
|
|
@@ -15918,7 +15915,7 @@ function resolveFilesystemPath(value) {
|
|
|
15918
15915
|
return path21.resolve(value);
|
|
15919
15916
|
}
|
|
15920
15917
|
try {
|
|
15921
|
-
return
|
|
15918
|
+
return fileURLToPath2(value);
|
|
15922
15919
|
} catch {
|
|
15923
15920
|
return path21.resolve(value.slice("file:".length));
|
|
15924
15921
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-6HY5F5FE.js";
|
|
3
3
|
import "./chunk-ZYADFKX3.js";
|
|
4
4
|
import "./chunk-GELCEVFA.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-UEGURBBW.js";
|
|
6
|
+
import "./chunk-FMQTRTWE.js";
|
|
7
7
|
import "./chunk-5LADPJ4C.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-6HY5F5FE.js";
|
|
3
3
|
import "./chunk-ZYADFKX3.js";
|
|
4
4
|
import "./chunk-GELCEVFA.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-UEGURBBW.js";
|
|
6
|
+
import "./chunk-FMQTRTWE.js";
|
|
7
7
|
import "./chunk-5LADPJ4C.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agenr",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Agent memory - local-first knowledge infrastructure for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@eslint/js": "^10.0.1",
|
|
28
28
|
"@types/node": "^25.5.0",
|
|
29
|
-
"skeln": "file:../skeln",
|
|
30
29
|
"typebox": "^1.1.38",
|
|
31
30
|
"eslint": "^10.1.0",
|
|
32
31
|
"eslint-plugin-jsdoc": "^62.8.1",
|
|
@@ -57,7 +56,11 @@
|
|
|
57
56
|
"lint": "eslint .",
|
|
58
57
|
"format": "prettier --write .",
|
|
59
58
|
"format:check": "prettier --check .",
|
|
59
|
+
"smoke:packages": "node scripts/package-smoke.mjs",
|
|
60
60
|
"test": "vitest run",
|
|
61
|
+
"test:win-sim": "node scripts/test-win-sim.mjs",
|
|
62
|
+
"test:docker": "node scripts/test-docker.mjs",
|
|
63
|
+
"test:docker:check": "node scripts/test-docker.mjs check",
|
|
61
64
|
"test:watch": "vitest"
|
|
62
65
|
}
|
|
63
66
|
}
|