openclaw-engram 0.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/dist/availability.d.ts +34 -0
- package/dist/availability.d.ts.map +1 -0
- package/dist/availability.js +70 -0
- package/dist/availability.js.map +1 -0
- package/dist/client.d.ts +147 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +199 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/memory.d.ts +11 -0
- package/dist/commands/memory.d.ts.map +1 -0
- package/dist/commands/memory.js +49 -0
- package/dist/commands/memory.js.map +1 -0
- package/dist/commands/remember.d.ts +15 -0
- package/dist/commands/remember.d.ts.map +1 -0
- package/dist/commands/remember.js +61 -0
- package/dist/commands/remember.js.map +1 -0
- package/dist/config.d.ts +73 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +81 -0
- package/dist/config.js.map +1 -0
- package/dist/context/formatter.d.ts +33 -0
- package/dist/context/formatter.d.ts.map +1 -0
- package/dist/context/formatter.js +193 -0
- package/dist/context/formatter.js.map +1 -0
- package/dist/hooks/after-tool-call.d.ts +19 -0
- package/dist/hooks/after-tool-call.d.ts.map +1 -0
- package/dist/hooks/after-tool-call.js +53 -0
- package/dist/hooks/after-tool-call.js.map +1 -0
- package/dist/hooks/before-compaction.d.ts +19 -0
- package/dist/hooks/before-compaction.d.ts.map +1 -0
- package/dist/hooks/before-compaction.js +60 -0
- package/dist/hooks/before-compaction.js.map +1 -0
- package/dist/hooks/before-prompt-build.d.ts +20 -0
- package/dist/hooks/before-prompt-build.d.ts.map +1 -0
- package/dist/hooks/before-prompt-build.js +76 -0
- package/dist/hooks/before-prompt-build.js.map +1 -0
- package/dist/hooks/session-end.d.ts +18 -0
- package/dist/hooks/session-end.d.ts.map +1 -0
- package/dist/hooks/session-end.js +57 -0
- package/dist/hooks/session-end.js.map +1 -0
- package/dist/hooks/session-start.d.ts +17 -0
- package/dist/hooks/session-start.d.ts.map +1 -0
- package/dist/hooks/session-start.js +77 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/identity.d.ts +36 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +106 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/dist/services/file-watcher.d.ts +11 -0
- package/dist/services/file-watcher.d.ts.map +1 -0
- package/dist/services/file-watcher.js +139 -0
- package/dist/services/file-watcher.js.map +1 -0
- package/dist/tools/engram-decisions.d.ts +8 -0
- package/dist/tools/engram-decisions.d.ts.map +1 -0
- package/dist/tools/engram-decisions.js +70 -0
- package/dist/tools/engram-decisions.js.map +1 -0
- package/dist/tools/engram-remember.d.ts +9 -0
- package/dist/tools/engram-remember.d.ts.map +1 -0
- package/dist/tools/engram-remember.js +116 -0
- package/dist/tools/engram-remember.js.map +1 -0
- package/dist/tools/engram-search.d.ts +9 -0
- package/dist/tools/engram-search.d.ts.map +1 -0
- package/dist/tools/engram-search.js +62 -0
- package/dist/tools/engram-search.js.map +1 -0
- package/dist/tools/memory-forget.d.ts +10 -0
- package/dist/tools/memory-forget.d.ts.map +1 -0
- package/dist/tools/memory-forget.js +41 -0
- package/dist/tools/memory-forget.js.map +1 -0
- package/dist/tools/memory-get.d.ts +11 -0
- package/dist/tools/memory-get.d.ts.map +1 -0
- package/dist/tools/memory-get.js +86 -0
- package/dist/tools/memory-get.js.map +1 -0
- package/dist/tools/memory-migrate.d.ts +11 -0
- package/dist/tools/memory-migrate.d.ts.map +1 -0
- package/dist/tools/memory-migrate.js +180 -0
- package/dist/tools/memory-migrate.js.map +1 -0
- package/dist/types/openclaw.d.ts +212 -0
- package/dist/types/openclaw.d.ts.map +1 -0
- package/dist/types/openclaw.js +9 -0
- package/dist/types/openclaw.js.map +1 -0
- package/dist/utils/memory-files.d.ts +25 -0
- package/dist/utils/memory-files.d.ts.map +1 -0
- package/dist/utils/memory-files.js +187 -0
- package/dist/utils/memory-files.js.map +1 -0
- package/openclaw.plugin.json +86 -0
- package/package.json +45 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passive availability detection with 3-strike circuit breaker.
|
|
3
|
+
*
|
|
4
|
+
* The tracker never polls engram — it only records outcomes of calls
|
|
5
|
+
* that the client already makes. After 3 consecutive failures the server
|
|
6
|
+
* is marked unavailable for a 60-second cooldown period, after which the
|
|
7
|
+
* next call is allowed through as a probe.
|
|
8
|
+
*/
|
|
9
|
+
export declare class AvailabilityTracker {
|
|
10
|
+
private consecutiveFailures;
|
|
11
|
+
private unavailableSince;
|
|
12
|
+
/**
|
|
13
|
+
* Record a successful call. Resets the failure counter and restores
|
|
14
|
+
* availability if the server was in cooldown.
|
|
15
|
+
*/
|
|
16
|
+
recordSuccess(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Record a failed call. After STRIKE_THRESHOLD consecutive failures
|
|
19
|
+
* the server enters a cooldown period.
|
|
20
|
+
*/
|
|
21
|
+
recordFailure(): void;
|
|
22
|
+
/**
|
|
23
|
+
* Returns true if the server is considered available.
|
|
24
|
+
*
|
|
25
|
+
* After the cooldown period expires the server is tentatively considered
|
|
26
|
+
* available again so that the next call can act as a probe. If that call
|
|
27
|
+
* succeeds, `recordSuccess()` completes the recovery. If it fails,
|
|
28
|
+
* `recordFailure()` restarts the cooldown immediately.
|
|
29
|
+
*/
|
|
30
|
+
isAvailable(): boolean;
|
|
31
|
+
/** Remaining cooldown in milliseconds, or 0 if available. */
|
|
32
|
+
remainingCooldownMs(): number;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=availability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"availability.d.ts","sourceRoot":"","sources":["../src/availability.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,gBAAgB,CAAuB;IAE/C;;;OAGG;IACH,aAAa,IAAI,IAAI;IASrB;;;OAGG;IACH,aAAa,IAAI,IAAI;IAWrB;;;;;;;OAOG;IACH,WAAW,IAAI,OAAO;IAYtB,6DAA6D;IAC7D,mBAAmB,IAAI,MAAM;CAK9B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Passive availability detection with 3-strike circuit breaker.
|
|
4
|
+
*
|
|
5
|
+
* The tracker never polls engram — it only records outcomes of calls
|
|
6
|
+
* that the client already makes. After 3 consecutive failures the server
|
|
7
|
+
* is marked unavailable for a 60-second cooldown period, after which the
|
|
8
|
+
* next call is allowed through as a probe.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.AvailabilityTracker = void 0;
|
|
12
|
+
const STRIKE_THRESHOLD = 3;
|
|
13
|
+
const COOLDOWN_MS = 60_000;
|
|
14
|
+
class AvailabilityTracker {
|
|
15
|
+
consecutiveFailures = 0;
|
|
16
|
+
unavailableSince = null;
|
|
17
|
+
/**
|
|
18
|
+
* Record a successful call. Resets the failure counter and restores
|
|
19
|
+
* availability if the server was in cooldown.
|
|
20
|
+
*/
|
|
21
|
+
recordSuccess() {
|
|
22
|
+
const wasUnavailable = this.unavailableSince !== null;
|
|
23
|
+
this.consecutiveFailures = 0;
|
|
24
|
+
this.unavailableSince = null;
|
|
25
|
+
if (wasUnavailable) {
|
|
26
|
+
console.warn('[engram] server is back online');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Record a failed call. After STRIKE_THRESHOLD consecutive failures
|
|
31
|
+
* the server enters a cooldown period.
|
|
32
|
+
*/
|
|
33
|
+
recordFailure() {
|
|
34
|
+
this.consecutiveFailures += 1;
|
|
35
|
+
if (this.consecutiveFailures >= STRIKE_THRESHOLD) {
|
|
36
|
+
this.unavailableSince = Date.now();
|
|
37
|
+
console.warn(`[engram] server marked unavailable after ${STRIKE_THRESHOLD} consecutive failures — ` +
|
|
38
|
+
`cooldown for ${COOLDOWN_MS / 1000}s`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns true if the server is considered available.
|
|
43
|
+
*
|
|
44
|
+
* After the cooldown period expires the server is tentatively considered
|
|
45
|
+
* available again so that the next call can act as a probe. If that call
|
|
46
|
+
* succeeds, `recordSuccess()` completes the recovery. If it fails,
|
|
47
|
+
* `recordFailure()` restarts the cooldown immediately.
|
|
48
|
+
*/
|
|
49
|
+
isAvailable() {
|
|
50
|
+
if (this.unavailableSince === null)
|
|
51
|
+
return true;
|
|
52
|
+
const elapsed = Date.now() - this.unavailableSince;
|
|
53
|
+
if (elapsed >= COOLDOWN_MS) {
|
|
54
|
+
// Cooldown expired — reset to allow one probe
|
|
55
|
+
this.consecutiveFailures = 0;
|
|
56
|
+
this.unavailableSince = null;
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
/** Remaining cooldown in milliseconds, or 0 if available. */
|
|
62
|
+
remainingCooldownMs() {
|
|
63
|
+
if (this.unavailableSince === null)
|
|
64
|
+
return 0;
|
|
65
|
+
const elapsed = Date.now() - this.unavailableSince;
|
|
66
|
+
return Math.max(0, COOLDOWN_MS - elapsed);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.AvailabilityTracker = AvailabilityTracker;
|
|
70
|
+
//# sourceMappingURL=availability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"availability.js","sourceRoot":"","sources":["../src/availability.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,WAAW,GAAG,MAAM,CAAC;AAE3B,MAAa,mBAAmB;IACtB,mBAAmB,GAAG,CAAC,CAAC;IACxB,gBAAgB,GAAkB,IAAI,CAAC;IAE/C;;;OAGG;IACH,aAAa;QACX,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC;QACtD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,mBAAmB,IAAI,gBAAgB,EAAE,CAAC;YACjD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CACV,4CAA4C,gBAAgB,0BAA0B;gBACpF,gBAAgB,WAAW,GAAG,IAAI,GAAG,CACxC,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,WAAW;QACT,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACnD,IAAI,OAAO,IAAI,WAAW,EAAE,CAAC;YAC3B,8CAA8C;YAC9C,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6DAA6D;IAC7D,mBAAmB;QACjB,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACnD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC;IAC5C,CAAC;CACF;AA1DD,kDA0DC"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EngramRestClient — typed REST client for the engram HTTP API.
|
|
3
|
+
*
|
|
4
|
+
* All methods return null on error and update the availability tracker.
|
|
5
|
+
* No method ever throws to its caller — engram failures must not block agent operation.
|
|
6
|
+
*/
|
|
7
|
+
import { AvailabilityTracker } from './availability.js';
|
|
8
|
+
import type { PluginConfig } from './config.js';
|
|
9
|
+
export interface Observation {
|
|
10
|
+
id: number;
|
|
11
|
+
title: string;
|
|
12
|
+
type: string;
|
|
13
|
+
scope?: string;
|
|
14
|
+
narrative?: string;
|
|
15
|
+
facts?: string[];
|
|
16
|
+
tags?: string[];
|
|
17
|
+
similarity?: number;
|
|
18
|
+
project?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ContextInjectResponse {
|
|
21
|
+
observations: Observation[];
|
|
22
|
+
sessionId?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ContextSearchResponse {
|
|
25
|
+
observations: Observation[];
|
|
26
|
+
}
|
|
27
|
+
export interface SessionInitResponse {
|
|
28
|
+
sessionDbId: number;
|
|
29
|
+
promptNumber: number;
|
|
30
|
+
skipped?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface HealthResponse {
|
|
33
|
+
status: string;
|
|
34
|
+
version?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface SelfCheckResponse {
|
|
37
|
+
components: Record<string, {
|
|
38
|
+
status: string;
|
|
39
|
+
message?: string;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
export interface BulkObservationInput {
|
|
43
|
+
title: string;
|
|
44
|
+
content: string;
|
|
45
|
+
type: string;
|
|
46
|
+
project: string;
|
|
47
|
+
scope?: string;
|
|
48
|
+
tags?: string[];
|
|
49
|
+
}
|
|
50
|
+
/** @deprecated Use BulkObservationInput instead. */
|
|
51
|
+
export type BulkImportRequest = BulkObservationInput;
|
|
52
|
+
export interface BulkImportResponse {
|
|
53
|
+
imported: number;
|
|
54
|
+
skipped_duplicates: number;
|
|
55
|
+
errors?: string[];
|
|
56
|
+
}
|
|
57
|
+
export interface BulkDeleteResponse {
|
|
58
|
+
deleted: number;
|
|
59
|
+
}
|
|
60
|
+
export declare class EngramRestClient {
|
|
61
|
+
private readonly baseUrl;
|
|
62
|
+
private readonly token;
|
|
63
|
+
private readonly defaultTimeoutMs;
|
|
64
|
+
readonly availability: AvailabilityTracker;
|
|
65
|
+
constructor(config: PluginConfig);
|
|
66
|
+
/**
|
|
67
|
+
* Fetch session context for injection (static session-level context).
|
|
68
|
+
* GET /api/context/inject?agent_id={id}&cwd={cwd}
|
|
69
|
+
*/
|
|
70
|
+
getContextInject(agentId: string, cwd?: string): Promise<ContextInjectResponse | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Per-turn context search.
|
|
73
|
+
* POST /api/context/search
|
|
74
|
+
*/
|
|
75
|
+
searchContext(body: {
|
|
76
|
+
project: string;
|
|
77
|
+
query: string;
|
|
78
|
+
cwd?: string;
|
|
79
|
+
agent_id?: string;
|
|
80
|
+
}): Promise<ContextSearchResponse | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Ingest a tool event for self-learning.
|
|
83
|
+
* POST /api/events/ingest (fire-and-forget — returns void)
|
|
84
|
+
*/
|
|
85
|
+
ingestEvent(body: {
|
|
86
|
+
session_id: string;
|
|
87
|
+
project: string;
|
|
88
|
+
tool_name: string;
|
|
89
|
+
tool_input: string;
|
|
90
|
+
tool_result: string;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Submit a transcript for session backfill/extraction.
|
|
94
|
+
* POST /api/backfill/session (fire-and-forget — returns void)
|
|
95
|
+
*/
|
|
96
|
+
backfillSession(body: {
|
|
97
|
+
session_id: string;
|
|
98
|
+
project: string;
|
|
99
|
+
content: string;
|
|
100
|
+
}): Promise<void>;
|
|
101
|
+
/**
|
|
102
|
+
* Initialize a new engram session for this agent interaction.
|
|
103
|
+
* POST /api/sessions/init
|
|
104
|
+
*/
|
|
105
|
+
initSession(body: {
|
|
106
|
+
claudeSessionId: string;
|
|
107
|
+
project: string;
|
|
108
|
+
prompt?: string;
|
|
109
|
+
}): Promise<SessionInitResponse | null>;
|
|
110
|
+
/**
|
|
111
|
+
* Mark observation IDs as injected into this session.
|
|
112
|
+
* POST /api/sessions/{id}/mark-injected (fire-and-forget)
|
|
113
|
+
*/
|
|
114
|
+
markInjected(sessionDbId: number, ids: number[]): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Health check.
|
|
117
|
+
* GET /api/health
|
|
118
|
+
*/
|
|
119
|
+
health(): Promise<HealthResponse | null>;
|
|
120
|
+
/**
|
|
121
|
+
* Component-level health check.
|
|
122
|
+
* GET /api/selfcheck
|
|
123
|
+
*/
|
|
124
|
+
selfCheck(): Promise<SelfCheckResponse | null>;
|
|
125
|
+
/**
|
|
126
|
+
* Bulk-import observations.
|
|
127
|
+
* POST /api/observations/bulk-import
|
|
128
|
+
*
|
|
129
|
+
* Server expects: { project, observations: [{ type, title, narrative, scope, concepts }] }
|
|
130
|
+
* Client uses: { content → narrative, tags → concepts }
|
|
131
|
+
*/
|
|
132
|
+
bulkImport(observations: BulkObservationInput[]): Promise<BulkImportResponse | null>;
|
|
133
|
+
/**
|
|
134
|
+
* Bulk-delete (archive) observations by ID.
|
|
135
|
+
* POST /api/observations/bulk-status { action: "archive", ids, reason }
|
|
136
|
+
*
|
|
137
|
+
* The server has no dedicated bulk-delete endpoint. Archiving is the closest
|
|
138
|
+
* equivalent — it removes observations from search results and context injection.
|
|
139
|
+
*/
|
|
140
|
+
bulkDelete(ids: string[]): Promise<BulkDeleteResponse | null>;
|
|
141
|
+
/** Returns true if the server is currently considered reachable. */
|
|
142
|
+
isAvailable(): boolean;
|
|
143
|
+
private get;
|
|
144
|
+
private post;
|
|
145
|
+
private request;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EngramRestClient — typed REST client for the engram HTTP API.
|
|
4
|
+
*
|
|
5
|
+
* All methods return null on error and update the availability tracker.
|
|
6
|
+
* No method ever throws to its caller — engram failures must not block agent operation.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.EngramRestClient = void 0;
|
|
10
|
+
const availability_js_1 = require("./availability.js");
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Client
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
class EngramRestClient {
|
|
15
|
+
baseUrl;
|
|
16
|
+
token;
|
|
17
|
+
defaultTimeoutMs;
|
|
18
|
+
availability;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
// Extract origin from potentially path-bearing URL
|
|
21
|
+
this.baseUrl = extractOrigin(config.url);
|
|
22
|
+
this.token = config.token;
|
|
23
|
+
this.defaultTimeoutMs = config.timeoutMs;
|
|
24
|
+
this.availability = new availability_js_1.AvailabilityTracker();
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Endpoints
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Fetch session context for injection (static session-level context).
|
|
31
|
+
* GET /api/context/inject?agent_id={id}&cwd={cwd}
|
|
32
|
+
*/
|
|
33
|
+
async getContextInject(agentId, cwd) {
|
|
34
|
+
const params = new URLSearchParams({ agent_id: agentId });
|
|
35
|
+
if (cwd)
|
|
36
|
+
params.set('cwd', cwd);
|
|
37
|
+
return this.get(`/api/context/inject?${params.toString()}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Per-turn context search.
|
|
41
|
+
* POST /api/context/search
|
|
42
|
+
*/
|
|
43
|
+
async searchContext(body) {
|
|
44
|
+
return this.post('/api/context/search', body);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Ingest a tool event for self-learning.
|
|
48
|
+
* POST /api/events/ingest (fire-and-forget — returns void)
|
|
49
|
+
*/
|
|
50
|
+
async ingestEvent(body) {
|
|
51
|
+
void this.post('/api/events/ingest', body, 3000);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Submit a transcript for session backfill/extraction.
|
|
55
|
+
* POST /api/backfill/session (fire-and-forget — returns void)
|
|
56
|
+
*/
|
|
57
|
+
async backfillSession(body) {
|
|
58
|
+
void this.post('/api/backfill/session', body, 5000);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Initialize a new engram session for this agent interaction.
|
|
62
|
+
* POST /api/sessions/init
|
|
63
|
+
*/
|
|
64
|
+
async initSession(body) {
|
|
65
|
+
return this.post('/api/sessions/init', body);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Mark observation IDs as injected into this session.
|
|
69
|
+
* POST /api/sessions/{id}/mark-injected (fire-and-forget)
|
|
70
|
+
*/
|
|
71
|
+
async markInjected(sessionDbId, ids) {
|
|
72
|
+
void this.post(`/api/sessions/${sessionDbId}/mark-injected`, { ids }, 3000);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Health check.
|
|
76
|
+
* GET /api/health
|
|
77
|
+
*/
|
|
78
|
+
async health() {
|
|
79
|
+
return this.get('/api/health', 3000);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Component-level health check.
|
|
83
|
+
* GET /api/selfcheck
|
|
84
|
+
*/
|
|
85
|
+
async selfCheck() {
|
|
86
|
+
return this.get('/api/selfcheck', 5000);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Bulk-import observations.
|
|
90
|
+
* POST /api/observations/bulk-import
|
|
91
|
+
*
|
|
92
|
+
* Server expects: { project, observations: [{ type, title, narrative, scope, concepts }] }
|
|
93
|
+
* Client uses: { content → narrative, tags → concepts }
|
|
94
|
+
*/
|
|
95
|
+
async bulkImport(observations) {
|
|
96
|
+
if (observations.length === 0)
|
|
97
|
+
return { imported: 0, skipped_duplicates: 0 };
|
|
98
|
+
// All observations in a batch must share the same project.
|
|
99
|
+
const project = observations[0].project;
|
|
100
|
+
const mapped = observations.map((o) => ({
|
|
101
|
+
type: o.type,
|
|
102
|
+
title: o.title,
|
|
103
|
+
narrative: o.content,
|
|
104
|
+
scope: o.scope,
|
|
105
|
+
concepts: o.tags,
|
|
106
|
+
}));
|
|
107
|
+
return this.post('/api/observations/bulk-import', {
|
|
108
|
+
project,
|
|
109
|
+
observations: mapped,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Bulk-delete (archive) observations by ID.
|
|
114
|
+
* POST /api/observations/bulk-status { action: "archive", ids, reason }
|
|
115
|
+
*
|
|
116
|
+
* The server has no dedicated bulk-delete endpoint. Archiving is the closest
|
|
117
|
+
* equivalent — it removes observations from search results and context injection.
|
|
118
|
+
*/
|
|
119
|
+
async bulkDelete(ids) {
|
|
120
|
+
const numericIds = ids.map((id) => Number(id)).filter((n) => !Number.isNaN(n));
|
|
121
|
+
if (numericIds.length === 0)
|
|
122
|
+
return { deleted: 0 };
|
|
123
|
+
const resp = await this.post('/api/observations/bulk-status', { action: 'archive', ids: numericIds, reason: 'Deleted via memory_forget' });
|
|
124
|
+
if (!resp)
|
|
125
|
+
return null;
|
|
126
|
+
return { deleted: resp.updated };
|
|
127
|
+
}
|
|
128
|
+
/** Returns true if the server is currently considered reachable. */
|
|
129
|
+
isAvailable() {
|
|
130
|
+
return this.availability.isAvailable();
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Internal HTTP helpers
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
async get(path, timeoutMs) {
|
|
136
|
+
return this.request('GET', path, undefined, timeoutMs);
|
|
137
|
+
}
|
|
138
|
+
async post(path, body, timeoutMs) {
|
|
139
|
+
return this.request('POST', path, body, timeoutMs);
|
|
140
|
+
}
|
|
141
|
+
async request(method, path, body, timeoutMs) {
|
|
142
|
+
if (!this.availability.isAvailable())
|
|
143
|
+
return null;
|
|
144
|
+
const url = this.baseUrl + path;
|
|
145
|
+
const timeout = timeoutMs ?? this.defaultTimeoutMs;
|
|
146
|
+
const controller = new AbortController();
|
|
147
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
148
|
+
try {
|
|
149
|
+
const headers = {
|
|
150
|
+
'Authorization': `Bearer ${this.token}`,
|
|
151
|
+
};
|
|
152
|
+
if (body !== undefined) {
|
|
153
|
+
headers['Content-Type'] = 'application/json';
|
|
154
|
+
}
|
|
155
|
+
const response = await fetch(url, {
|
|
156
|
+
method,
|
|
157
|
+
headers,
|
|
158
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
159
|
+
signal: controller.signal,
|
|
160
|
+
});
|
|
161
|
+
const text = await response.text();
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
throw new Error(`HTTP ${response.status} ${response.statusText}: ${text}`);
|
|
164
|
+
}
|
|
165
|
+
this.availability.recordSuccess();
|
|
166
|
+
if (!text)
|
|
167
|
+
return null;
|
|
168
|
+
return JSON.parse(text);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
this.availability.recordFailure();
|
|
172
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
173
|
+
console.error(`[engram] ${method} ${path} failed: ${msg}`);
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.EngramRestClient = EngramRestClient;
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// Helpers
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
/**
|
|
186
|
+
* Extract the origin (protocol + host) from a URL that may include a path.
|
|
187
|
+
* Falls back to trimming the trailing segment on parse failure.
|
|
188
|
+
*/
|
|
189
|
+
function extractOrigin(rawUrl) {
|
|
190
|
+
const trimmed = rawUrl.trim();
|
|
191
|
+
try {
|
|
192
|
+
const parsed = new URL(trimmed);
|
|
193
|
+
return `${parsed.protocol}//${parsed.host}${parsed.pathname.replace(/\/+$/, '')}`;
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return trimmed.replace(/\/$/, '');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /memory command — shows engram server status and recent context overview.
|
|
3
|
+
*/
|
|
4
|
+
import type { EngramRestClient } from '../client.js';
|
|
5
|
+
import type { PluginConfig } from '../config.js';
|
|
6
|
+
import type { OpenClawPluginCommandDefinition } from '../types/openclaw.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build the /memory command definition.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildMemoryCommand(client: EngramRestClient, config: PluginConfig): OpenClawPluginCommandDefinition;
|
|
11
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/commands/memory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,+BAA+B,EAAwB,MAAM,sBAAsB,CAAC;AAElG;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,+BAA+B,CA4CjC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* /memory command — shows engram server status and recent context overview.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildMemoryCommand = buildMemoryCommand;
|
|
7
|
+
/**
|
|
8
|
+
* Build the /memory command definition.
|
|
9
|
+
*/
|
|
10
|
+
function buildMemoryCommand(client, config) {
|
|
11
|
+
return {
|
|
12
|
+
name: 'memory',
|
|
13
|
+
description: 'Show engram memory server status and recent observations',
|
|
14
|
+
acceptsArgs: false,
|
|
15
|
+
async handler(_ctx) {
|
|
16
|
+
if (!client.isAvailable()) {
|
|
17
|
+
const cooldown = client.availability.remainingCooldownMs();
|
|
18
|
+
return {
|
|
19
|
+
text: `engram status: UNAVAILABLE\n` +
|
|
20
|
+
`Server: ${config.url}\n` +
|
|
21
|
+
(cooldown > 0 ? `Retry in: ${Math.ceil(cooldown / 1000)}s\n` : ''),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const [health, selfCheck] = await Promise.all([
|
|
25
|
+
client.health(),
|
|
26
|
+
client.selfCheck(),
|
|
27
|
+
]);
|
|
28
|
+
const lines = [];
|
|
29
|
+
lines.push(`engram status: ${health?.status ?? 'UNKNOWN'}`);
|
|
30
|
+
lines.push(`Server: ${config.url}`);
|
|
31
|
+
if (health?.version)
|
|
32
|
+
lines.push(`Version: ${health.version}`);
|
|
33
|
+
if (selfCheck?.components) {
|
|
34
|
+
lines.push('\nComponents:');
|
|
35
|
+
for (const [name, comp] of Object.entries(selfCheck.components)) {
|
|
36
|
+
const icon = comp.status === 'ok' ? 'OK' : 'WARN';
|
|
37
|
+
lines.push(` [${icon}] ${name}${comp.message ? ': ' + comp.message : ''}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
lines.push(`\nConfig:`);
|
|
41
|
+
lines.push(` Token budget: ${config.tokenBudget} tokens`);
|
|
42
|
+
lines.push(` Context limit: ${config.contextLimit} observations/turn`);
|
|
43
|
+
lines.push(` Session context limit: ${config.sessionContextLimit} observations`);
|
|
44
|
+
lines.push(` Auto-extract: ${config.autoExtract ? 'enabled' : 'disabled'}`);
|
|
45
|
+
return { text: lines.join('\n') };
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/commands/memory.ts"],"names":[],"mappings":";AAAA;;GAEG;;AASH,gDA+CC;AAlDD;;GAEG;AACH,SAAgB,kBAAkB,CAChC,MAAwB,EACxB,MAAoB;IAEpB,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0DAA0D;QACvE,WAAW,EAAE,KAAK;QAElB,KAAK,CAAC,OAAO,CAAC,IAA0B;YACtC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,mBAAmB,EAAE,CAAC;gBAC3D,OAAO;oBACL,IAAI,EACF,8BAA8B;wBAC9B,WAAW,MAAM,CAAC,GAAG,IAAI;wBACzB,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrE,CAAC;YACJ,CAAC;YAED,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC5C,MAAM,CAAC,MAAM,EAAE;gBACf,MAAM,CAAC,SAAS,EAAE;aACnB,CAAC,CAAC;YAEH,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,EAAE,MAAM,IAAI,SAAS,EAAE,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;YACpC,IAAI,MAAM,EAAE,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAE9D,IAAI,SAAS,EAAE,UAAU,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;oBAChE,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;oBAClD,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,WAAW,SAAS,CAAC,CAAC;YAC3D,KAAK,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,YAAY,oBAAoB,CAAC,CAAC;YACxE,KAAK,CAAC,IAAI,CAAC,4BAA4B,MAAM,CAAC,mBAAmB,eAAe,CAAC,CAAC;YAClF,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;YAE7E,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /remember command — quick observation storage shortcut.
|
|
3
|
+
*
|
|
4
|
+
* Usage: /remember <text>
|
|
5
|
+
*
|
|
6
|
+
* Stores the provided text as a "change" type observation in the current project.
|
|
7
|
+
*/
|
|
8
|
+
import type { EngramRestClient } from '../client.js';
|
|
9
|
+
import type { PluginConfig } from '../config.js';
|
|
10
|
+
import type { OpenClawPluginCommandDefinition } from '../types/openclaw.js';
|
|
11
|
+
/**
|
|
12
|
+
* Build the /remember command definition.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildRememberCommand(client: EngramRestClient, config: PluginConfig): OpenClawPluginCommandDefinition;
|
|
15
|
+
//# sourceMappingURL=remember.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remember.d.ts","sourceRoot":"","sources":["../../src/commands/remember.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAqB,MAAM,cAAc,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAE,+BAA+B,EAAwB,MAAM,sBAAsB,CAAC;AAIlG;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,YAAY,GACnB,+BAA+B,CAsDjC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* /remember command — quick observation storage shortcut.
|
|
4
|
+
*
|
|
5
|
+
* Usage: /remember <text>
|
|
6
|
+
*
|
|
7
|
+
* Stores the provided text as a "change" type observation in the current project.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildRememberCommand = buildRememberCommand;
|
|
11
|
+
const identity_js_1 = require("../identity.js");
|
|
12
|
+
const CONTENT_MAX_CHARS = 900;
|
|
13
|
+
/**
|
|
14
|
+
* Build the /remember command definition.
|
|
15
|
+
*/
|
|
16
|
+
function buildRememberCommand(client, config) {
|
|
17
|
+
return {
|
|
18
|
+
name: 'remember',
|
|
19
|
+
description: 'Quickly store a note in engram memory',
|
|
20
|
+
acceptsArgs: true,
|
|
21
|
+
async handler(ctx) {
|
|
22
|
+
const text = (ctx.args ?? '').trim();
|
|
23
|
+
if (!text) {
|
|
24
|
+
return { text: 'Usage: /remember <text to remember>' };
|
|
25
|
+
}
|
|
26
|
+
if (!client.isAvailable()) {
|
|
27
|
+
return { text: 'engram is currently unreachable — cannot store memory' };
|
|
28
|
+
}
|
|
29
|
+
const identity = (0, identity_js_1.resolveIdentity)('', config.workspaceDir ?? process.cwd());
|
|
30
|
+
const project = config.project ?? identity.projectId;
|
|
31
|
+
// Use the first sentence (up to 80 chars) as the title
|
|
32
|
+
const firstSentence = text.split(/[.!?]/)[0]?.trim() ?? text;
|
|
33
|
+
const title = firstSentence.length > 80
|
|
34
|
+
? firstSentence.slice(0, 77) + '...'
|
|
35
|
+
: firstSentence;
|
|
36
|
+
const content = text.length > CONTENT_MAX_CHARS
|
|
37
|
+
? text.slice(0, CONTENT_MAX_CHARS)
|
|
38
|
+
: text;
|
|
39
|
+
const observation = {
|
|
40
|
+
title,
|
|
41
|
+
content,
|
|
42
|
+
type: 'change',
|
|
43
|
+
project,
|
|
44
|
+
scope: 'project',
|
|
45
|
+
};
|
|
46
|
+
const response = await client.bulkImport([observation]);
|
|
47
|
+
if (!response) {
|
|
48
|
+
return { text: 'Failed to store memory — engram returned no response' };
|
|
49
|
+
}
|
|
50
|
+
if (response.imported > 0) {
|
|
51
|
+
return { text: `Stored: "${title}"` };
|
|
52
|
+
}
|
|
53
|
+
if (response.skipped_duplicates > 0) {
|
|
54
|
+
return { text: `Skipped (likely a near-duplicate): "${title}"` };
|
|
55
|
+
}
|
|
56
|
+
const errMsg = response.errors?.join(', ') ?? 'unknown error';
|
|
57
|
+
return { text: `Failed to store memory: ${errMsg}` };
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=remember.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remember.js","sourceRoot":"","sources":["../../src/commands/remember.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAYH,oDAyDC;AAjED,gDAAiD;AAGjD,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAE9B;;GAEG;AACH,SAAgB,oBAAoB,CAClC,MAAwB,EACxB,MAAoB;IAEpB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,uCAAuC;QACpD,WAAW,EAAE,IAAI;QAEjB,KAAK,CAAC,OAAO,CAAC,GAAyB;YACrC,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,EAAE,IAAI,EAAE,qCAAqC,EAAE,CAAC;YACzD,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC1B,OAAO,EAAE,IAAI,EAAE,uDAAuD,EAAE,CAAC;YAC3E,CAAC;YAED,MAAM,QAAQ,GAAG,IAAA,6BAAe,EAAC,EAAE,EAAE,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC3E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,SAAS,CAAC;YAErD,uDAAuD;YACvD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;YAC7D,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,EAAE;gBACrC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK;gBACpC,CAAC,CAAC,aAAa,CAAC;YAElB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,iBAAiB;gBAC7C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC;gBAClC,CAAC,CAAC,IAAI,CAAC;YAET,MAAM,WAAW,GAAsB;gBACrC,KAAK;gBACL,OAAO;gBACP,IAAI,EAAE,QAAQ;gBACd,OAAO;gBACP,KAAK,EAAE,SAAS;aACjB,CAAC;YAEF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,EAAE,IAAI,EAAE,sDAAsD,EAAE,CAAC;YAC1E,CAAC;YAED,IAAI,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,IAAI,EAAE,YAAY,KAAK,GAAG,EAAE,CAAC;YACxC,CAAC;YAED,IAAI,QAAQ,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;gBACpC,OAAO,EAAE,IAAI,EAAE,uCAAuC,KAAK,GAAG,EAAE,CAAC;YACnE,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;YAC9D,OAAO,EAAE,IAAI,EAAE,2BAA2B,MAAM,EAAE,EAAE,CAAC;QACvD,CAAC;KACF,CAAC;AACJ,CAAC"}
|