@memoryblock/core 0.1.4
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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/engine/agent.d.ts +15 -0
- package/dist/engine/agent.d.ts.map +1 -0
- package/dist/engine/agent.js +19 -0
- package/dist/engine/agent.js.map +1 -0
- package/dist/engine/conversation-log.d.ts +35 -0
- package/dist/engine/conversation-log.d.ts.map +1 -0
- package/dist/engine/conversation-log.js +83 -0
- package/dist/engine/conversation-log.js.map +1 -0
- package/dist/engine/cost-tracker.d.ts +52 -0
- package/dist/engine/cost-tracker.d.ts.map +1 -0
- package/dist/engine/cost-tracker.js +110 -0
- package/dist/engine/cost-tracker.js.map +1 -0
- package/dist/engine/gatekeeper.d.ts +20 -0
- package/dist/engine/gatekeeper.d.ts.map +1 -0
- package/dist/engine/gatekeeper.js +43 -0
- package/dist/engine/gatekeeper.js.map +1 -0
- package/dist/engine/memory.d.ts +28 -0
- package/dist/engine/memory.d.ts.map +1 -0
- package/dist/engine/memory.js +69 -0
- package/dist/engine/memory.js.map +1 -0
- package/dist/engine/monitor.d.ts +81 -0
- package/dist/engine/monitor.d.ts.map +1 -0
- package/dist/engine/monitor.js +610 -0
- package/dist/engine/monitor.js.map +1 -0
- package/dist/engine/prompts.d.ts +31 -0
- package/dist/engine/prompts.d.ts.map +1 -0
- package/dist/engine/prompts.js +93 -0
- package/dist/engine/prompts.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +24 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +86 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/fs.d.ts +18 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +65 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +40 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present memoryblock
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @memoryblock/core
|
|
2
|
+
The core engine and runtime for **memoryblock**.
|
|
3
|
+
|
|
4
|
+
This package handles:
|
|
5
|
+
- Monitor loops and background processes
|
|
6
|
+
- Memory manager and state persistence
|
|
7
|
+
- Gatekeeper and safety boundaries
|
|
8
|
+
- Agent orchestration and tool execution
|
|
9
|
+
|
|
10
|
+
## The `memoryblock` Ecosystem
|
|
11
|
+
|
|
12
|
+
**memoryblock** is a highly modular system. Here are the official packages:
|
|
13
|
+
|
|
14
|
+
**The Core**
|
|
15
|
+
* [**memoryblock**](https://www.npmjs.com/package/memoryblock) - CLI orchestrator and command routing.
|
|
16
|
+
* [**@memoryblock/core**](https://www.npmjs.com/package/@memoryblock/core) - Engine runtime, memory manager, gatekeeper.
|
|
17
|
+
* [**@memoryblock/types**](https://www.npmjs.com/package/@memoryblock/types) - Shared TypeScript definitions and schemas.
|
|
18
|
+
* [**@memoryblock/locale**](https://www.npmjs.com/package/@memoryblock/locale) - Localization strings and utilities.
|
|
19
|
+
|
|
20
|
+
**Integrations & Tooling**
|
|
21
|
+
* [**@memoryblock/adapters**](https://www.npmjs.com/package/@memoryblock/adapters) - LLM provider adapters (OpenAI, Anthropic, Bedrock, etc).
|
|
22
|
+
* [**@memoryblock/channels**](https://www.npmjs.com/package/@memoryblock/channels) - Communication channels (CLI, Telegram, Web).
|
|
23
|
+
* [**@memoryblock/tools**](https://www.npmjs.com/package/@memoryblock/tools) - Tool registry and built-in definitions.
|
|
24
|
+
* [**@memoryblock/daemon**](https://www.npmjs.com/package/@memoryblock/daemon) - Background process spawner and manager.
|
|
25
|
+
* [**@memoryblock/api**](https://www.npmjs.com/package/@memoryblock/api) - HTTP/WebSocket API server.
|
|
26
|
+
* [**@memoryblock/web**](https://www.npmjs.com/package/@memoryblock/web) - Front-end dashboard static files.
|
|
27
|
+
|
|
28
|
+
**Plugins**
|
|
29
|
+
* [**@memoryblock/plugin-installer**](https://www.npmjs.com/package/@memoryblock/plugin-installer) - Plugin installer and registry manager.
|
|
30
|
+
* [**@memoryblock/plugin-agents**](https://www.npmjs.com/package/@memoryblock/plugin-agents) - Secondary AI agents orchestrator.
|
|
31
|
+
* [**@memoryblock/plugin-aws**](https://www.npmjs.com/package/@memoryblock/plugin-aws) - AWS integrations.
|
|
32
|
+
* [**@memoryblock/plugin-fetch-webpage**](https://www.npmjs.com/package/@memoryblock/plugin-fetch-webpage) - Web content fetching and parsing.
|
|
33
|
+
* [**@memoryblock/plugin-web-search**](https://www.npmjs.com/package/@memoryblock/plugin-web-search) - Web search capabilities.
|
|
34
|
+
|
|
35
|
+
## License
|
|
36
|
+
|
|
37
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent: Ephemeral worker spawned by the Monitor.
|
|
3
|
+
* Lives in blocks/<name>/agents/<agent-id>/
|
|
4
|
+
* Has its own memory and tool scope.
|
|
5
|
+
*
|
|
6
|
+
* MVP: Placeholder — Monitor can function without agents.
|
|
7
|
+
* Full agent spawning will be implemented post-MVP.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Agent {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly role: string;
|
|
12
|
+
readonly agentPath: string;
|
|
13
|
+
constructor(id: string, role: string, agentPath: string);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/engine/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,KAAK;IACd,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAK1D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent: Ephemeral worker spawned by the Monitor.
|
|
3
|
+
* Lives in blocks/<name>/agents/<agent-id>/
|
|
4
|
+
* Has its own memory and tool scope.
|
|
5
|
+
*
|
|
6
|
+
* MVP: Placeholder — Monitor can function without agents.
|
|
7
|
+
* Full agent spawning will be implemented post-MVP.
|
|
8
|
+
*/
|
|
9
|
+
export class Agent {
|
|
10
|
+
id;
|
|
11
|
+
role;
|
|
12
|
+
agentPath;
|
|
13
|
+
constructor(id, role, agentPath) {
|
|
14
|
+
this.id = id;
|
|
15
|
+
this.role = role;
|
|
16
|
+
this.agentPath = agentPath;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/engine/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,OAAO,KAAK;IACL,EAAE,CAAS;IACX,IAAI,CAAS;IACb,SAAS,CAAS;IAE3B,YAAY,EAAU,EAAE,IAAY,EAAE,SAAiB;QACnD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;CACJ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversation logger — writes all interactions to timestamped .txt files
|
|
3
|
+
* in the block's logs/ directory.
|
|
4
|
+
*
|
|
5
|
+
* Log format:
|
|
6
|
+
* ---
|
|
7
|
+
* [2025-03-12 00:09:51] [CHANNEL:telegram] [FROM:user] [CHAT:5315436002]
|
|
8
|
+
* Hello, how are you?
|
|
9
|
+
*
|
|
10
|
+
* [2025-03-12 00:09:54] [CHANNEL:telegram] [FROM:monitor:Sam] [EMOJI:🌟]
|
|
11
|
+
* I'm doing well! How can I help you today?
|
|
12
|
+
* ---
|
|
13
|
+
*/
|
|
14
|
+
export declare class ConversationLogger {
|
|
15
|
+
private logDir;
|
|
16
|
+
private logFile;
|
|
17
|
+
private buffer;
|
|
18
|
+
private flushTimer;
|
|
19
|
+
constructor(blockPath: string);
|
|
20
|
+
init(blockName: string, monitorName: string, channelType: string): Promise<void>;
|
|
21
|
+
logUser(content: string, meta: {
|
|
22
|
+
channel: string;
|
|
23
|
+
chatId?: string;
|
|
24
|
+
}): void;
|
|
25
|
+
logMonitor(content: string, meta: {
|
|
26
|
+
channel: string;
|
|
27
|
+
monitorName: string;
|
|
28
|
+
emoji?: string;
|
|
29
|
+
}): void;
|
|
30
|
+
logSystem(message: string): void;
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
private scheduleFlush;
|
|
33
|
+
private flush;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=conversation-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-log.d.ts","sourceRoot":"","sources":["../../src/engine/conversation-log.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAA8C;gBAEpD,SAAS,EAAE,MAAM;IAMvB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBtF,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQ1E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQjG,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAO1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,OAAO,CAAC,aAAa;YAKP,KAAK;CAMtB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { promises as fsp } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Conversation logger — writes all interactions to timestamped .txt files
|
|
5
|
+
* in the block's logs/ directory.
|
|
6
|
+
*
|
|
7
|
+
* Log format:
|
|
8
|
+
* ---
|
|
9
|
+
* [2025-03-12 00:09:51] [CHANNEL:telegram] [FROM:user] [CHAT:5315436002]
|
|
10
|
+
* Hello, how are you?
|
|
11
|
+
*
|
|
12
|
+
* [2025-03-12 00:09:54] [CHANNEL:telegram] [FROM:monitor:Sam] [EMOJI:🌟]
|
|
13
|
+
* I'm doing well! How can I help you today?
|
|
14
|
+
* ---
|
|
15
|
+
*/
|
|
16
|
+
export class ConversationLogger {
|
|
17
|
+
logDir;
|
|
18
|
+
logFile;
|
|
19
|
+
buffer = [];
|
|
20
|
+
flushTimer = null;
|
|
21
|
+
constructor(blockPath) {
|
|
22
|
+
this.logDir = join(blockPath, 'logs');
|
|
23
|
+
// Temporary filename until init() provides block name and channel
|
|
24
|
+
this.logFile = join(this.logDir, `session-${Date.now()}.txt`);
|
|
25
|
+
}
|
|
26
|
+
async init(blockName, monitorName, channelType) {
|
|
27
|
+
await fsp.mkdir(this.logDir, { recursive: true });
|
|
28
|
+
// Build filename: {blockName}-{channelType}-{timestamp}.txt
|
|
29
|
+
const now = new Date();
|
|
30
|
+
const stamp = now.toISOString().replace('T', '_').replace(/:/g, '-').slice(0, 16);
|
|
31
|
+
this.logFile = join(this.logDir, `${blockName}-${channelType}-${stamp}.txt`);
|
|
32
|
+
const header = [
|
|
33
|
+
'═'.repeat(60),
|
|
34
|
+
`SESSION START: ${new Date().toISOString()}`,
|
|
35
|
+
`Block: ${blockName}`,
|
|
36
|
+
`Monitor: ${monitorName}`,
|
|
37
|
+
`Channel: ${channelType}`,
|
|
38
|
+
'═'.repeat(60),
|
|
39
|
+
'',
|
|
40
|
+
].join('\n');
|
|
41
|
+
await fsp.writeFile(this.logFile, header, 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
logUser(content, meta) {
|
|
44
|
+
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
45
|
+
const chatPart = meta.chatId ? ` [CHAT:${meta.chatId}]` : '';
|
|
46
|
+
const entry = `[${ts}] [CHANNEL:${meta.channel}] [FROM:user]${chatPart}\n${content}\n\n`;
|
|
47
|
+
this.buffer.push(entry);
|
|
48
|
+
this.scheduleFlush();
|
|
49
|
+
}
|
|
50
|
+
logMonitor(content, meta) {
|
|
51
|
+
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
52
|
+
const emojiPart = meta.emoji ? ` [EMOJI:${meta.emoji}]` : '';
|
|
53
|
+
const entry = `[${ts}] [CHANNEL:${meta.channel}] [FROM:monitor:${meta.monitorName}]${emojiPart}\n${content}\n\n`;
|
|
54
|
+
this.buffer.push(entry);
|
|
55
|
+
this.scheduleFlush();
|
|
56
|
+
}
|
|
57
|
+
logSystem(message) {
|
|
58
|
+
const ts = new Date().toISOString().replace('T', ' ').slice(0, 19);
|
|
59
|
+
const entry = `[${ts}] [SYSTEM]\n${message}\n\n`;
|
|
60
|
+
this.buffer.push(entry);
|
|
61
|
+
this.scheduleFlush();
|
|
62
|
+
}
|
|
63
|
+
async close() {
|
|
64
|
+
if (this.flushTimer)
|
|
65
|
+
clearTimeout(this.flushTimer);
|
|
66
|
+
await this.flush();
|
|
67
|
+
const footer = `\n${'═'.repeat(60)}\nSESSION END: ${new Date().toISOString()}\n${'═'.repeat(60)}\n`;
|
|
68
|
+
await fsp.appendFile(this.logFile, footer, 'utf-8');
|
|
69
|
+
}
|
|
70
|
+
scheduleFlush() {
|
|
71
|
+
if (this.flushTimer)
|
|
72
|
+
clearTimeout(this.flushTimer);
|
|
73
|
+
this.flushTimer = setTimeout(() => this.flush(), 500);
|
|
74
|
+
}
|
|
75
|
+
async flush() {
|
|
76
|
+
if (!this.buffer.length)
|
|
77
|
+
return;
|
|
78
|
+
const content = this.buffer.join('');
|
|
79
|
+
this.buffer = [];
|
|
80
|
+
await fsp.appendFile(this.logFile, content, 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=conversation-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-log.js","sourceRoot":"","sources":["../../src/engine/conversation-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { TokenUsage } from '@memoryblock/types';
|
|
2
|
+
interface CostSnapshot {
|
|
3
|
+
sessionInput: number;
|
|
4
|
+
sessionOutput: number;
|
|
5
|
+
totalInput: number;
|
|
6
|
+
totalOutput: number;
|
|
7
|
+
sessionCost: number;
|
|
8
|
+
totalCost: number;
|
|
9
|
+
lastUpdated: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* System-level cost tracker — tracks tokens and calculates USD cost.
|
|
13
|
+
* Persists to costs.json in the block directory.
|
|
14
|
+
* No model tokens wasted — this is pure system bookkeeping.
|
|
15
|
+
*/
|
|
16
|
+
export declare class CostTracker {
|
|
17
|
+
private model;
|
|
18
|
+
private pricing;
|
|
19
|
+
private sessionInput;
|
|
20
|
+
private sessionOutput;
|
|
21
|
+
private totalInput;
|
|
22
|
+
private totalOutput;
|
|
23
|
+
private turnCount;
|
|
24
|
+
private lastTurnInput;
|
|
25
|
+
private lastTurnOutput;
|
|
26
|
+
private costFile;
|
|
27
|
+
constructor(blockPath: string, model: string);
|
|
28
|
+
/** Load previous totals from costs.json. */
|
|
29
|
+
load(): Promise<void>;
|
|
30
|
+
/** Track a single API call's usage. */
|
|
31
|
+
track(usage: TokenUsage): void;
|
|
32
|
+
/** Get session cost in USD. */
|
|
33
|
+
getSessionCost(): number;
|
|
34
|
+
/** Get total cost in USD (all sessions). */
|
|
35
|
+
getTotalCost(): number;
|
|
36
|
+
/** Format cost for display. */
|
|
37
|
+
formatCost(cost: number): string;
|
|
38
|
+
/** Get formatted session report. */
|
|
39
|
+
getSessionReport(): string;
|
|
40
|
+
/** Get per-turn report for the last API call. */
|
|
41
|
+
getPerTurnReport(): string;
|
|
42
|
+
/** Get all-time total report. */
|
|
43
|
+
getTotalReport(): string;
|
|
44
|
+
/** Get turn count. */
|
|
45
|
+
getTurnCount(): number;
|
|
46
|
+
/** Get snapshot for display / persistence. */
|
|
47
|
+
getSnapshot(): CostSnapshot;
|
|
48
|
+
/** Persist to costs.json. */
|
|
49
|
+
save(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../src/engine/cost-tracker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAmBrD,UAAU,YAAY;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAS;gBAEb,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAO5C,4CAA4C;IACtC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,uCAAuC;IACvC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAU9B,+BAA+B;IAC/B,cAAc,IAAI,MAAM;IAKxB,4CAA4C;IAC5C,YAAY,IAAI,MAAM;IAKtB,+BAA+B;IAC/B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIhC,oCAAoC;IACpC,gBAAgB,IAAI,MAAM;IAI1B,iDAAiD;IACjD,gBAAgB,IAAI,MAAM;IAI1B,iCAAiC;IACjC,cAAc,IAAI,MAAM;IAIxB,sBAAsB;IACtB,YAAY,IAAI,MAAM;IAItB,8CAA8C;IAC9C,WAAW,IAAI,YAAY;IAY3B,6BAA6B;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAI9B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { promises as fsp } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Pricing per 1M tokens (USD) — system-level, zero model tokens used.
|
|
5
|
+
* Source: AWS Bedrock / Anthropic pricing pages.
|
|
6
|
+
*/
|
|
7
|
+
const MODEL_PRICING = {
|
|
8
|
+
// Opus
|
|
9
|
+
'us.anthropic.claude-opus-4-6-v1': { input: 15, output: 75 },
|
|
10
|
+
'us.anthropic.claude-opus-4-20250514-v1:0': { input: 15, output: 75 },
|
|
11
|
+
// Sonnet
|
|
12
|
+
'us.anthropic.claude-sonnet-4-20250514-v1:0': { input: 3, output: 15 },
|
|
13
|
+
'us.anthropic.claude-sonnet-4-5-20250929-v1:0': { input: 3, output: 15 },
|
|
14
|
+
// Haiku
|
|
15
|
+
'us.anthropic.claude-3-5-haiku-20241022-v1:0': { input: 0.80, output: 4 },
|
|
16
|
+
};
|
|
17
|
+
const DEFAULT_PRICING = { input: 3, output: 15 };
|
|
18
|
+
/**
|
|
19
|
+
* System-level cost tracker — tracks tokens and calculates USD cost.
|
|
20
|
+
* Persists to costs.json in the block directory.
|
|
21
|
+
* No model tokens wasted — this is pure system bookkeeping.
|
|
22
|
+
*/
|
|
23
|
+
export class CostTracker {
|
|
24
|
+
model;
|
|
25
|
+
pricing;
|
|
26
|
+
sessionInput = 0;
|
|
27
|
+
sessionOutput = 0;
|
|
28
|
+
totalInput = 0;
|
|
29
|
+
totalOutput = 0;
|
|
30
|
+
turnCount = 0;
|
|
31
|
+
lastTurnInput = 0;
|
|
32
|
+
lastTurnOutput = 0;
|
|
33
|
+
costFile;
|
|
34
|
+
constructor(blockPath, model) {
|
|
35
|
+
this.model = model;
|
|
36
|
+
this.costFile = join(blockPath, 'costs.json');
|
|
37
|
+
// Find pricing or use default
|
|
38
|
+
this.pricing = MODEL_PRICING[model] || DEFAULT_PRICING;
|
|
39
|
+
}
|
|
40
|
+
/** Load previous totals from costs.json. */
|
|
41
|
+
async load() {
|
|
42
|
+
try {
|
|
43
|
+
const raw = await fsp.readFile(this.costFile, 'utf-8');
|
|
44
|
+
const data = JSON.parse(raw);
|
|
45
|
+
this.totalInput = data.totalInput || 0;
|
|
46
|
+
this.totalOutput = data.totalOutput || 0;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// First run — no file
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Track a single API call's usage. */
|
|
53
|
+
track(usage) {
|
|
54
|
+
this.lastTurnInput = usage.inputTokens;
|
|
55
|
+
this.lastTurnOutput = usage.outputTokens;
|
|
56
|
+
this.sessionInput += usage.inputTokens;
|
|
57
|
+
this.sessionOutput += usage.outputTokens;
|
|
58
|
+
this.totalInput += usage.inputTokens;
|
|
59
|
+
this.totalOutput += usage.outputTokens;
|
|
60
|
+
this.turnCount++;
|
|
61
|
+
}
|
|
62
|
+
/** Get session cost in USD. */
|
|
63
|
+
getSessionCost() {
|
|
64
|
+
return (this.sessionInput / 1_000_000) * this.pricing.input +
|
|
65
|
+
(this.sessionOutput / 1_000_000) * this.pricing.output;
|
|
66
|
+
}
|
|
67
|
+
/** Get total cost in USD (all sessions). */
|
|
68
|
+
getTotalCost() {
|
|
69
|
+
return (this.totalInput / 1_000_000) * this.pricing.input +
|
|
70
|
+
(this.totalOutput / 1_000_000) * this.pricing.output;
|
|
71
|
+
}
|
|
72
|
+
/** Format cost for display. */
|
|
73
|
+
formatCost(cost) {
|
|
74
|
+
return `$${cost.toFixed(4)}`;
|
|
75
|
+
}
|
|
76
|
+
/** Get formatted session report. */
|
|
77
|
+
getSessionReport() {
|
|
78
|
+
return `${this.sessionInput.toLocaleString()} in / ${this.sessionOutput.toLocaleString()} out`;
|
|
79
|
+
}
|
|
80
|
+
/** Get per-turn report for the last API call. */
|
|
81
|
+
getPerTurnReport() {
|
|
82
|
+
return `${this.lastTurnInput.toLocaleString()} in / ${this.lastTurnOutput.toLocaleString()} out`;
|
|
83
|
+
}
|
|
84
|
+
/** Get all-time total report. */
|
|
85
|
+
getTotalReport() {
|
|
86
|
+
return `${this.totalInput.toLocaleString()} in / ${this.totalOutput.toLocaleString()} out`;
|
|
87
|
+
}
|
|
88
|
+
/** Get turn count. */
|
|
89
|
+
getTurnCount() {
|
|
90
|
+
return this.turnCount;
|
|
91
|
+
}
|
|
92
|
+
/** Get snapshot for display / persistence. */
|
|
93
|
+
getSnapshot() {
|
|
94
|
+
return {
|
|
95
|
+
sessionInput: this.sessionInput,
|
|
96
|
+
sessionOutput: this.sessionOutput,
|
|
97
|
+
totalInput: this.totalInput,
|
|
98
|
+
totalOutput: this.totalOutput,
|
|
99
|
+
sessionCost: this.getSessionCost(),
|
|
100
|
+
totalCost: this.getTotalCost(),
|
|
101
|
+
lastUpdated: new Date().toISOString(),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Persist to costs.json. */
|
|
105
|
+
async save() {
|
|
106
|
+
const snapshot = this.getSnapshot();
|
|
107
|
+
await fsp.writeFile(this.costFile, JSON.stringify(snapshot, null, 2), 'utf-8');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../src/engine/cost-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Channel } from '@memoryblock/types';
|
|
2
|
+
/**
|
|
3
|
+
* Gatekeeper: The sovereign human approval system.
|
|
4
|
+
* When a tool requires approval (e.g., shell commands), execution pauses
|
|
5
|
+
* and the system requests explicit human approval via the active channel.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Gatekeeper {
|
|
8
|
+
private channel;
|
|
9
|
+
private blockName;
|
|
10
|
+
private monitorName;
|
|
11
|
+
constructor(channel: Channel, blockName: string, monitorName: string);
|
|
12
|
+
/**
|
|
13
|
+
* Request human approval for a tool execution.
|
|
14
|
+
* Returns true if approved, false if denied.
|
|
15
|
+
*/
|
|
16
|
+
requestApproval(toolName: string, toolInput: Record<string, unknown>): Promise<boolean>;
|
|
17
|
+
/** Format a human-readable description of the action. */
|
|
18
|
+
private formatDescription;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=gatekeeper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatekeeper.d.ts","sourceRoot":"","sources":["../../src/engine/gatekeeper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAmB,MAAM,oBAAoB,CAAC;AAGnE;;;;GAIG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMpE;;;OAGG;IACG,eAAe,CACjB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,OAAO,CAAC,OAAO,CAAC;IAgBnB,yDAAyD;IACzD,OAAO,CAAC,iBAAiB;CAS5B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { log } from '../utils/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Gatekeeper: The sovereign human approval system.
|
|
4
|
+
* When a tool requires approval (e.g., shell commands), execution pauses
|
|
5
|
+
* and the system requests explicit human approval via the active channel.
|
|
6
|
+
*/
|
|
7
|
+
export class Gatekeeper {
|
|
8
|
+
channel;
|
|
9
|
+
blockName;
|
|
10
|
+
monitorName;
|
|
11
|
+
constructor(channel, blockName, monitorName) {
|
|
12
|
+
this.channel = channel;
|
|
13
|
+
this.blockName = blockName;
|
|
14
|
+
this.monitorName = monitorName;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Request human approval for a tool execution.
|
|
18
|
+
* Returns true if approved, false if denied.
|
|
19
|
+
*/
|
|
20
|
+
async requestApproval(toolName, toolInput) {
|
|
21
|
+
const description = this.formatDescription(toolName, toolInput);
|
|
22
|
+
const request = {
|
|
23
|
+
toolName,
|
|
24
|
+
toolInput,
|
|
25
|
+
description,
|
|
26
|
+
blockName: this.blockName,
|
|
27
|
+
monitorName: this.monitorName,
|
|
28
|
+
};
|
|
29
|
+
log.system(this.blockName, `Approval required: ${description}`);
|
|
30
|
+
return this.channel.requestApproval(request);
|
|
31
|
+
}
|
|
32
|
+
/** Format a human-readable description of the action. */
|
|
33
|
+
formatDescription(toolName, input) {
|
|
34
|
+
if (toolName === 'execute_command') {
|
|
35
|
+
return `Run command: ${input.command}`;
|
|
36
|
+
}
|
|
37
|
+
const params = Object.entries(input)
|
|
38
|
+
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
|
39
|
+
.join(', ');
|
|
40
|
+
return `${toolName}(${params})`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=gatekeeper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gatekeeper.js","sourceRoot":"","sources":["../../src/engine/gatekeeper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;;;GAIG;AACH,MAAM,OAAO,UAAU;IACX,OAAO,CAAU;IACjB,SAAS,CAAS;IAClB,WAAW,CAAS;IAE5B,YAAY,OAAgB,EAAE,SAAiB,EAAE,WAAmB;QAChE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CACjB,QAAgB,EAChB,SAAkC;QAElC,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAEhE,MAAM,OAAO,GAAoB;YAC7B,QAAQ;YACR,SAAS;YACT,WAAW;YACX,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;SAChC,CAAC;QAEF,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,sBAAsB,WAAW,EAAE,CAAC,CAAC;QAEhE,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,yDAAyD;IACjD,iBAAiB,CAAC,QAAgB,EAAE,KAA8B;QACtE,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;YACjC,OAAO,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC;QAC3C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAC/B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5C,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO,GAAG,QAAQ,IAAI,MAAM,GAAG,CAAC;IACpC,CAAC;CACJ"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LLMAdapter, LLMMessage, TokenUsage } from '@memoryblock/types';
|
|
2
|
+
/**
|
|
3
|
+
* Memory Manager: Implements the 80% rule.
|
|
4
|
+
* When the active session hits the threshold, the LLM summarizes its learnings
|
|
5
|
+
* into memory.md, and the session is reborn with fresh context.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MemoryManager {
|
|
8
|
+
private readonly maxTokens;
|
|
9
|
+
private readonly threshold;
|
|
10
|
+
private accumulatedTokens;
|
|
11
|
+
constructor(maxContextTokens: number, thresholdPercent: number);
|
|
12
|
+
/** Track token usage from a response. */
|
|
13
|
+
trackUsage(usage: TokenUsage): void;
|
|
14
|
+
/** Check if the accumulated tokens exceed the threshold. */
|
|
15
|
+
shouldSummarize(): boolean;
|
|
16
|
+
/** Get current token count. */
|
|
17
|
+
getTokenCount(): number;
|
|
18
|
+
/** Reset token tracking after a rebirth. */
|
|
19
|
+
reset(): void;
|
|
20
|
+
/** Load the block's memory.md. */
|
|
21
|
+
loadMemory(blockPath: string): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
* Summarize the current session and write to memory.md.
|
|
24
|
+
* Asks the LLM to distill its learnings.
|
|
25
|
+
*/
|
|
26
|
+
summarize(adapter: LLMAdapter, messages: LLMMessage[], blockPath: string): Promise<string>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/engine/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAK7E;;;;GAIG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,iBAAiB,CAAa;gBAE1B,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM;IAK9D,yCAAyC;IACzC,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAInC,4DAA4D;IAC5D,eAAe,IAAI,OAAO;IAI1B,+BAA+B;IAC/B,aAAa,IAAI,MAAM;IAIvB,4CAA4C;IAC5C,KAAK,IAAI,IAAI;IAIb,kCAAkC;IAC5B,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIpD;;;OAGG;IACG,SAAS,CACX,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,UAAU,EAAE,EACtB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;CAiCrB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { readTextSafe, atomicWrite } from '../utils/fs.js';
|
|
2
|
+
import { log } from '../utils/logger.js';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Memory Manager: Implements the 80% rule.
|
|
6
|
+
* When the active session hits the threshold, the LLM summarizes its learnings
|
|
7
|
+
* into memory.md, and the session is reborn with fresh context.
|
|
8
|
+
*/
|
|
9
|
+
export class MemoryManager {
|
|
10
|
+
maxTokens;
|
|
11
|
+
threshold; // 0-1
|
|
12
|
+
accumulatedTokens = 0;
|
|
13
|
+
constructor(maxContextTokens, thresholdPercent) {
|
|
14
|
+
this.maxTokens = maxContextTokens;
|
|
15
|
+
this.threshold = thresholdPercent / 100;
|
|
16
|
+
}
|
|
17
|
+
/** Track token usage from a response. */
|
|
18
|
+
trackUsage(usage) {
|
|
19
|
+
this.accumulatedTokens += usage.totalTokens;
|
|
20
|
+
}
|
|
21
|
+
/** Check if the accumulated tokens exceed the threshold. */
|
|
22
|
+
shouldSummarize() {
|
|
23
|
+
return this.accumulatedTokens >= this.maxTokens * this.threshold;
|
|
24
|
+
}
|
|
25
|
+
/** Get current token count. */
|
|
26
|
+
getTokenCount() {
|
|
27
|
+
return this.accumulatedTokens;
|
|
28
|
+
}
|
|
29
|
+
/** Reset token tracking after a rebirth. */
|
|
30
|
+
reset() {
|
|
31
|
+
this.accumulatedTokens = 0;
|
|
32
|
+
}
|
|
33
|
+
/** Load the block's memory.md. */
|
|
34
|
+
async loadMemory(blockPath) {
|
|
35
|
+
return readTextSafe(join(blockPath, 'memory.md'), '');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Summarize the current session and write to memory.md.
|
|
39
|
+
* Asks the LLM to distill its learnings.
|
|
40
|
+
*/
|
|
41
|
+
async summarize(adapter, messages, blockPath) {
|
|
42
|
+
const summarizePrompt = [
|
|
43
|
+
{
|
|
44
|
+
role: 'system',
|
|
45
|
+
content: 'You are a memory manager. Summarize the conversation into a structured memory document. ' +
|
|
46
|
+
'Include: key decisions made, important context, current goals, progress toward those goals, ' +
|
|
47
|
+
'and what should be done next. Write in markdown format. ' +
|
|
48
|
+
'CRITICAL: Keep the summary under 1500 words. Be concise. Omit pleasantries and redundancy.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
role: 'user',
|
|
52
|
+
content: 'Summarize this conversation for your future self. Focus on what was accomplished, ' +
|
|
53
|
+
'key learnings, and next steps:\n\n' +
|
|
54
|
+
messages
|
|
55
|
+
.filter((m) => m.role !== 'system')
|
|
56
|
+
.map((m) => `[${m.role}]: ${(m.content || '(tool interaction)').slice(0, 300)}`)
|
|
57
|
+
.join('\n'),
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
const response = await adapter.converse(summarizePrompt);
|
|
61
|
+
const summary = response.message.content || '';
|
|
62
|
+
const memoryContent = `# Monitor Memory\n\n> Last updated: ${new Date().toISOString()}\n\n${summary}\n`;
|
|
63
|
+
await atomicWrite(join(blockPath, 'memory.md'), memoryContent);
|
|
64
|
+
log.info(`Memory summarized (${this.accumulatedTokens} tokens → rebirth)`);
|
|
65
|
+
this.reset();
|
|
66
|
+
return memoryContent;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/engine/memory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,aAAa;IACL,SAAS,CAAS;IAClB,SAAS,CAAS,CAAC,MAAM;IAClC,iBAAiB,GAAW,CAAC,CAAC;IAEtC,YAAY,gBAAwB,EAAE,gBAAwB;QAC1D,IAAI,CAAC,SAAS,GAAG,gBAAgB,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,gBAAgB,GAAG,GAAG,CAAC;IAC5C,CAAC;IAED,yCAAyC;IACzC,UAAU,CAAC,KAAiB;QACxB,IAAI,CAAC,iBAAiB,IAAI,KAAK,CAAC,WAAW,CAAC;IAChD,CAAC;IAED,4DAA4D;IAC5D,eAAe;QACX,OAAO,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IACrE,CAAC;IAED,+BAA+B;IAC/B,aAAa;QACT,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAClC,CAAC;IAED,4CAA4C;IAC5C,KAAK;QACD,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,kCAAkC;IAClC,KAAK,CAAC,UAAU,CAAC,SAAiB;QAC9B,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,SAAS,CACX,OAAmB,EACnB,QAAsB,EACtB,SAAiB;QAEjB,MAAM,eAAe,GAAiB;YAClC;gBACI,IAAI,EAAE,QAAQ;gBACd,OAAO,EACH,0FAA0F;oBAC1F,8FAA8F;oBAC9F,0DAA0D;oBAC1D,4FAA4F;aACnG;YACD;gBACI,IAAI,EAAE,MAAM;gBACZ,OAAO,EACH,oFAAoF;oBACpF,oCAAoC;oBACpC,QAAQ;yBACH,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;yBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;yBAC/E,IAAI,CAAC,IAAI,CAAC;aACtB;SACJ,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAE/C,MAAM,aAAa,GAAG,uCAAuC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,OAAO,IAAI,CAAC;QACxG,MAAM,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,aAAa,CAAC,CAAC;QAE/D,GAAG,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,iBAAiB,oBAAoB,CAAC,CAAC;QAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,OAAO,aAAa,CAAC;IACzB,CAAC;CACJ"}
|