@aiaiaichain/agent 0.1.6 → 0.1.7

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.
Files changed (121) hide show
  1. package/dist/api/ExtensionAPI.d.ts +0 -1
  2. package/dist/api/ExtensionAPI.js +3 -7
  3. package/dist/api/Registry.d.ts +0 -1
  4. package/dist/api/Registry.js +54 -57
  5. package/dist/cli.d.ts +0 -1
  6. package/dist/cli.js +683 -686
  7. package/dist/core/AgentDir.d.ts +1 -1
  8. package/dist/core/AgentDir.js +45 -39
  9. package/dist/core/ChainConfig.d.ts +0 -1
  10. package/dist/core/ChainConfig.js +51 -55
  11. package/dist/core/EnvLoader.d.ts +4 -1
  12. package/dist/core/EnvLoader.js +97 -84
  13. package/dist/core/SystemMonitor.d.ts +0 -1
  14. package/dist/core/SystemMonitor.js +72 -85
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +19 -26
  17. package/dist/loader.d.ts +0 -1
  18. package/dist/loader.js +64 -67
  19. package/dist/mcp/entry.d.ts +0 -1
  20. package/dist/mcp/entry.js +3 -6
  21. package/dist/mcp/server.d.ts +0 -1
  22. package/dist/mcp/server.js +152 -156
  23. package/dist/models/CostTracker.d.ts +0 -1
  24. package/dist/models/CostTracker.js +58 -61
  25. package/dist/models/ModelRegistry.d.ts +0 -1
  26. package/dist/models/ModelRegistry.js +195 -155
  27. package/dist/providers/ProviderRegistry.d.ts +0 -1
  28. package/dist/providers/ProviderRegistry.js +33 -36
  29. package/dist/runner/AgentRunner.d.ts +0 -1
  30. package/dist/runner/AgentRunner.js +180 -184
  31. package/dist/runner/ModelClient.d.ts +0 -1
  32. package/dist/runner/ModelClient.js +133 -134
  33. package/dist/runner/SwarmRouter.d.ts +0 -1
  34. package/dist/runner/SwarmRouter.js +18 -22
  35. package/dist/runner/ToolDispatcher.d.ts +0 -1
  36. package/dist/runner/ToolDispatcher.js +30 -33
  37. package/dist/scheduler/AgentScheduler.d.ts +0 -1
  38. package/dist/scheduler/AgentScheduler.js +99 -103
  39. package/dist/session/ContextStore.d.ts +1 -1
  40. package/dist/session/ContextStore.js +76 -78
  41. package/dist/session/GoalManager.d.ts +0 -1
  42. package/dist/session/GoalManager.js +96 -100
  43. package/dist/session/MemoryStore.d.ts +2 -1
  44. package/dist/session/MemoryStore.js +108 -87
  45. package/dist/session/SessionManager.d.ts +5 -4
  46. package/dist/session/SessionManager.js +83 -62
  47. package/dist/session/SessionStore.d.ts +0 -1
  48. package/dist/session/SessionStore.js +112 -116
  49. package/dist/setup/SetupWizard.d.ts +0 -1
  50. package/dist/setup/SetupWizard.js +61 -64
  51. package/dist/tools/CrossTools.d.ts +0 -1
  52. package/dist/tools/CrossTools.js +140 -144
  53. package/dist/tools/GmgnIntegration.d.ts +0 -1
  54. package/dist/tools/GmgnIntegration.js +220 -230
  55. package/dist/tools/MarketSentiment.d.ts +0 -1
  56. package/dist/tools/MarketSentiment.js +213 -195
  57. package/dist/tools/NewsSentiment.d.ts +0 -1
  58. package/dist/tools/NewsSentiment.js +126 -130
  59. package/dist/tools/PriceFeed.d.ts +6 -1
  60. package/dist/tools/PriceFeed.js +201 -133
  61. package/dist/tools/TechnicalAnalysis.d.ts +1 -2
  62. package/dist/tools/TechnicalAnalysis.js +248 -216
  63. package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
  64. package/dist/tools/TechnicalAnalysis.worker.js +92 -0
  65. package/dist/tools/TokenCalendar.d.ts +0 -1
  66. package/dist/tools/TokenCalendar.js +63 -68
  67. package/dist/tools/TokenSecurityScanner.d.ts +0 -1
  68. package/dist/tools/TokenSecurityScanner.js +93 -96
  69. package/dist/tools/TransactionSim.d.ts +0 -1
  70. package/dist/tools/TransactionSim.js +65 -71
  71. package/dist/tui/App.d.ts +0 -1
  72. package/dist/tui/App.js +895 -824
  73. package/dist/tui/ModelSelector.d.ts +0 -1
  74. package/dist/tui/ModelSelector.js +46 -49
  75. package/dist/tui/REPL.d.ts +0 -1
  76. package/dist/tui/REPL.js +222 -210
  77. package/dist/tui/Sparkline.d.ts +0 -1
  78. package/dist/tui/Sparkline.js +36 -37
  79. package/dist/tui/StatusBar.d.ts +0 -1
  80. package/dist/tui/StatusBar.js +9 -10
  81. package/dist/tui/ThemePresets.d.ts +0 -1
  82. package/dist/tui/ThemePresets.js +99 -103
  83. package/dist/tui/theme.d.ts +0 -1
  84. package/dist/tui/theme.js +50 -31
  85. package/dist/util/clipboard.d.ts +0 -1
  86. package/dist/util/clipboard.js +16 -20
  87. package/dist/util/commandSuggest.d.ts +0 -1
  88. package/dist/util/commandSuggest.js +34 -38
  89. package/dist/util/confirmation.d.ts +0 -1
  90. package/dist/util/confirmation.js +8 -11
  91. package/dist/util/errorHandler.d.ts +0 -1
  92. package/dist/util/errorHandler.js +20 -23
  93. package/dist/util/errors.d.ts +59 -0
  94. package/dist/util/errors.js +93 -0
  95. package/dist/util/logger.d.ts +0 -1
  96. package/dist/util/logger.js +30 -33
  97. package/dist/util/processManager.d.ts +0 -1
  98. package/dist/util/processManager.js +33 -36
  99. package/dist/util/resilientFetch.d.ts +6 -1
  100. package/dist/util/resilientFetch.js +134 -80
  101. package/dist/util/responseCache.d.ts +0 -1
  102. package/dist/util/responseCache.js +36 -45
  103. package/dist/util/rpc.d.ts +16 -0
  104. package/dist/util/rpc.js +69 -0
  105. package/dist/util/safeLog.d.ts +0 -1
  106. package/dist/util/safeLog.js +52 -53
  107. package/dist/util/scheduler.d.ts +0 -1
  108. package/dist/util/scheduler.js +53 -58
  109. package/dist/util/webhooks.d.ts +0 -1
  110. package/dist/util/webhooks.js +54 -58
  111. package/dist/wallet/ActionFeed.d.ts +0 -1
  112. package/dist/wallet/ActionFeed.js +189 -200
  113. package/dist/wallet/AgentWallet.d.ts +7 -8
  114. package/dist/wallet/AgentWallet.js +117 -144
  115. package/dist/wallet/ProfitTracker.d.ts +0 -1
  116. package/dist/wallet/ProfitTracker.js +71 -74
  117. package/package.json +11 -6
  118. package/scripts/build-esbuild.mjs +40 -0
  119. package/scripts/bundle-dts.mjs +58 -0
  120. package/scripts/minify.mjs +44 -0
  121. package/scripts/postinstall.js +27 -0
@@ -1,108 +1,104 @@
1
- /**
2
- * GoalManager — persistent cross-session goals for the agent to monitor and complete.
3
- * Goals are stored in ~/.aiaiai/memory/goals.json
4
- */
1
+
5
2
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
6
3
  import { resolve } from "node:path";
7
4
  import { Type } from "@sinclair/typebox";
8
5
  import { AgentDir } from "../core/AgentDir.js";
9
6
  const GOALS_PATH = resolve(AgentDir.getHome(), "memory", "goals.json");
10
7
  export class GoalManager {
11
- goals = [];
12
- constructor() {
13
- this.load();
14
- }
15
- load() {
16
- try {
17
- if (existsSync(GOALS_PATH)) {
18
- this.goals = JSON.parse(readFileSync(GOALS_PATH, "utf-8"));
19
- }
20
- }
21
- catch {
22
- this.goals = [];
23
- }
24
- }
25
- save() {
26
- try {
27
- writeFileSync(GOALS_PATH, JSON.stringify(this.goals, null, 2), "utf-8");
28
- }
29
- catch { /* non-fatal */ }
30
- }
31
- addGoal(text) {
32
- const goal = {
33
- id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
34
- text,
35
- status: "active",
36
- createdAt: Date.now(),
37
- notes: [],
38
- };
39
- this.goals.push(goal);
40
- this.save();
41
- return goal;
42
- }
43
- completeGoal(id) {
44
- const goal = this.goals.find(g => g.id === id);
45
- if (!goal)
46
- return false;
47
- goal.status = "completed";
48
- goal.completedAt = Date.now();
49
- this.save();
50
- return true;
51
- }
52
- addNote(id, note) {
53
- const goal = this.goals.find(g => g.id === id);
54
- if (!goal)
55
- return false;
56
- goal.notes.push(note);
57
- this.save();
58
- return true;
59
- }
60
- listGoals(status) {
61
- if (!status || status === "all")
62
- return [...this.goals];
63
- return this.goals.filter(g => g.status === status);
64
- }
65
- buildContextBlock() {
66
- const active = this.goals.filter(g => g.status === "active");
67
- if (active.length === 0)
68
- return "";
69
- const lines = active.map(g => ` [${g.id}] ${g.text.slice(0, 200)}`);
70
- return `\n\n[ACTIVE GOALS]\n${lines.join("\n")}\n`;
71
- }
72
- // ── Tools ───────────────────────────────────────────────────────────────
73
- setGoalParams = Type.Object({
74
- text: Type.String({ description: "Goal description" }),
75
- });
76
- completeGoalParams = Type.Object({
77
- id: Type.String({ description: "Goal ID to complete" }),
78
- });
79
- listGoalsParams = Type.Object({
80
- status: Type.Optional(Type.String({ description: "Filter: active, completed, or all" })),
81
- });
82
- addGoalNoteParams = Type.Object({
83
- id: Type.String({ description: "Goal ID" }),
84
- note: Type.String({ description: "Progress note" }),
85
- });
86
- async setGoalTool(_id, params) {
87
- const goal = this.addGoal(params.text);
88
- return { content: [{ type: "text", text: `Goal created: "${goal.text}" (${goal.id})` }] };
89
- }
90
- async completeGoalTool(_id, params) {
91
- const ok = this.completeGoal(params.id);
92
- return { content: [{ type: "text", text: ok ? `Goal ${params.id} completed ✅` : `Goal ${params.id} not found` }] };
93
- }
94
- async listGoalsTool(_id, params) {
95
- const status = params.status || "active";
96
- const goals = this.listGoals(status);
97
- if (goals.length === 0)
98
- return { content: [{ type: "text", text: "No goals found." }] };
99
- const lines = goals.map(g => ` ${g.status === "completed" ? "✅" : "🎯"} ${g.id} — ${g.text.slice(0, 120)}${g.notes.length > 0 ? ` (${g.notes.length} notes)` : ""}`);
100
- return { content: [{ type: "text", text: `Goals (${goals.length}):\n${lines.join("\n")}` }] };
101
- }
102
- async addGoalNoteTool(_id, params) {
103
- const ok = this.addNote(params.id, params.note);
104
- return { content: [{ type: "text", text: ok ? `Note added to ${params.id}` : `Goal ${params.id} not found` }] };
105
- }
8
+ goals = [];
9
+ constructor() {
10
+ this.load();
11
+ }
12
+ load() {
13
+ try {
14
+ if (existsSync(GOALS_PATH)) {
15
+ this.goals = JSON.parse(readFileSync(GOALS_PATH, "utf-8"));
16
+ }
17
+ }
18
+ catch {
19
+ this.goals = [];
20
+ }
21
+ }
22
+ save() {
23
+ try {
24
+ writeFileSync(GOALS_PATH, JSON.stringify(this.goals, null, 2), "utf-8");
25
+ }
26
+ catch { }
27
+ }
28
+ addGoal(text) {
29
+ const goal = {
30
+ id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
31
+ text,
32
+ status: "active",
33
+ createdAt: Date.now(),
34
+ notes: [],
35
+ };
36
+ this.goals.push(goal);
37
+ this.save();
38
+ return goal;
39
+ }
40
+ completeGoal(id) {
41
+ const goal = this.goals.find(g => g.id === id);
42
+ if (!goal)
43
+ return false;
44
+ goal.status = "completed";
45
+ goal.completedAt = Date.now();
46
+ this.save();
47
+ return true;
48
+ }
49
+ addNote(id, note) {
50
+ const goal = this.goals.find(g => g.id === id);
51
+ if (!goal)
52
+ return false;
53
+ goal.notes.push(note);
54
+ this.save();
55
+ return true;
56
+ }
57
+ listGoals(status) {
58
+ if (!status || status === "all")
59
+ return [...this.goals];
60
+ return this.goals.filter(g => g.status === status);
61
+ }
62
+ buildContextBlock() {
63
+ const active = this.goals.filter(g => g.status === "active");
64
+ if (active.length === 0)
65
+ return "";
66
+ const lines = active.map(g => ` [${g.id}] ${g.text.slice(0, 200)}`);
67
+ return `\n\n[ACTIVE GOALS]\n${lines.join("\n")}\n`;
68
+ }
69
+
70
+ setGoalParams = Type.Object({
71
+ text: Type.String({ description: "Goal description" }),
72
+ });
73
+ completeGoalParams = Type.Object({
74
+ id: Type.String({ description: "Goal ID to complete" }),
75
+ });
76
+ listGoalsParams = Type.Object({
77
+ status: Type.Optional(Type.String({ description: "Filter: active, completed, or all" })),
78
+ });
79
+ addGoalNoteParams = Type.Object({
80
+ id: Type.String({ description: "Goal ID" }),
81
+ note: Type.String({ description: "Progress note" }),
82
+ });
83
+ async setGoalTool(_id, params) {
84
+ const goal = this.addGoal(params.text);
85
+ return { content: [{ type: "text", text: `Goal created: "${goal.text}" (${goal.id})` }] };
86
+ }
87
+ async completeGoalTool(_id, params) {
88
+ const ok = this.completeGoal(params.id);
89
+ return { content: [{ type: "text", text: ok ? `Goal ${params.id} completed ✅` : `Goal ${params.id} not found` }] };
90
+ }
91
+ async listGoalsTool(_id, params) {
92
+ const status = params.status || "active";
93
+ const goals = this.listGoals(status);
94
+ if (goals.length === 0)
95
+ return { content: [{ type: "text", text: "No goals found." }] };
96
+ const lines = goals.map(g => ` ${g.status === "completed" ? "✅" : "🎯"} ${g.id} — ${g.text.slice(0, 120)}${g.notes.length > 0 ? ` (${g.notes.length} notes)` : ""}`);
97
+ return { content: [{ type: "text", text: `Goals (${goals.length}):\n${lines.join("\n")}` }] };
98
+ }
99
+ async addGoalNoteTool(_id, params) {
100
+ const ok = this.addNote(params.id, params.note);
101
+ return { content: [{ type: "text", text: ok ? `Note added to ${params.id}` : `Goal ${params.id} not found` }] };
102
+ }
106
103
  }
107
104
  export const goalManager = new GoalManager();
108
- //# sourceMappingURL=GoalManager.js.map
@@ -19,9 +19,10 @@ export declare class MemoryStore {
19
19
  private available;
20
20
  constructor();
21
21
  get isAvailable(): boolean;
22
+ private lineCounts;
22
23
  save(sessionId: string, role: "user" | "assistant" | "system", content: string): void;
24
+ private compactFile;
23
25
  search(query: string, limit?: number): MemoryEntry[];
24
26
  buildContextBlock(sessionId: string): string;
25
27
  }
26
28
  export declare const memoryStore: MemoryStore;
27
- //# sourceMappingURL=MemoryStore.d.ts.map
@@ -1,92 +1,113 @@
1
- /**
2
- * MemoryStore persistent long-term memory for agents.
3
- * Stored in ~/.aiaiai/memory/ as JSONL files per session.
4
- */
5
- import { existsSync, readFileSync, appendFileSync, mkdirSync, readdirSync } from "node:fs";
1
+
2
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, readdirSync } from "node:fs";
6
3
  import { resolve } from "node:path";
7
4
  import { AgentDir } from "../core/AgentDir.js";
8
5
  export class MemoryStore {
9
- basePath;
10
- available = false;
11
- constructor() {
12
- this.basePath = resolve(AgentDir.getHome(), "memory");
13
- try {
14
- if (!existsSync(this.basePath))
15
- mkdirSync(this.basePath, { recursive: true });
16
- this.available = true;
17
- }
18
- catch {
19
- this.available = false;
20
- }
21
- }
22
- get isAvailable() { return this.available; }
23
- save(sessionId, role, content) {
24
- if (!this.available)
25
- return;
26
- const entry = {
27
- id: `mem-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
28
- sessionId,
29
- role,
30
- content: content.slice(0, 500), // Cap individual entries
31
- ts: Date.now(),
32
- };
33
- try {
34
- appendFileSync(resolve(this.basePath, `${sessionId}.jsonl`), JSON.stringify(entry) + "\n", "utf-8");
35
- }
36
- catch { /* non-fatal */ }
37
- }
38
- search(query, limit = 8) {
39
- if (!this.available)
40
- return [];
41
- try {
42
- const all = [];
43
- const files = readdirSync(this.basePath).filter((f) => f.endsWith(".jsonl"));
44
- for (const file of files) {
45
- const content = readFileSync(resolve(this.basePath, file), "utf-8");
46
- for (const line of content.split("\n").filter(Boolean)) {
47
- try {
48
- all.push(JSON.parse(line));
49
- }
50
- catch {
51
- continue;
52
- }
53
- }
54
- }
55
- const q = query.toLowerCase().trim();
56
- const results = all.filter(e => e.content && e.content.toLowerCase().includes(q));
57
- return results.sort((a, b) => b.ts - a.ts).slice(0, limit);
58
- }
59
- catch {
60
- return [];
61
- }
62
- }
63
- buildContextBlock(sessionId) {
64
- if (!this.available)
65
- return "";
66
- try {
67
- const path = resolve(this.basePath, `${sessionId}.jsonl`);
68
- if (!existsSync(path))
69
- return "";
70
- const lines = readFileSync(path, "utf-8").split("\n").filter(Boolean);
71
- if (lines.length < 3)
72
- return "";
73
- // Build a compact memory summary from previous turns
74
- const entries = lines.slice(-20).map(l => { try {
75
- return JSON.parse(l);
76
- }
77
- catch {
78
- return null;
79
- } }).filter(Boolean);
80
- if (entries.length < 2)
81
- return "";
82
- const recent = entries.slice(-6);
83
- const summaries = recent.map(e => `[${e.role}]: ${e.content.slice(0, 150)}`);
84
- return `\n\n[RECENT MEMORY]\n${summaries.join("\n")}\n`;
85
- }
86
- catch {
87
- return "";
88
- }
89
- }
6
+ basePath;
7
+ available = false;
8
+ constructor() {
9
+ this.basePath = resolve(AgentDir.getHome(), "memory");
10
+ try {
11
+ if (!existsSync(this.basePath))
12
+ mkdirSync(this.basePath, { recursive: true });
13
+ this.available = true;
14
+ }
15
+ catch {
16
+ this.available = false;
17
+ }
18
+ }
19
+ get isAvailable() { return this.available; }
20
+
21
+ lineCounts = new Map();
22
+ save(sessionId, role, content) {
23
+ if (!this.available)
24
+ return;
25
+ const entry = {
26
+ id: `mem-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
27
+ sessionId,
28
+ role,
29
+ content: content.slice(0, 500),
30
+ ts: Date.now(),
31
+ };
32
+ try {
33
+ appendFileSync(resolve(this.basePath, `${sessionId}.jsonl`), JSON.stringify(entry) + "\n", "utf-8");
34
+
35
+ const count = (this.lineCounts.get(sessionId) ?? 0) + 1;
36
+ this.lineCounts.set(sessionId, count);
37
+ if (count > 200) {
38
+ this.compactFile(sessionId);
39
+ this.lineCounts.set(sessionId, 0);
40
+ }
41
+ }
42
+ catch { }
43
+ }
44
+
45
+ compactFile(sessionId) {
46
+ try {
47
+ const path = resolve(this.basePath, `${sessionId}.jsonl`);
48
+ if (!existsSync(path))
49
+ return;
50
+ const content = readFileSync(path, "utf-8");
51
+ const lines = content.split("\n").filter(Boolean);
52
+ if (lines.length <= 200)
53
+ return;
54
+
55
+ const kept = lines.slice(-100);
56
+ writeFileSync(path, kept.join("\n") + "\n", "utf-8");
57
+ }
58
+ catch { }
59
+ }
60
+ search(query, limit = 8) {
61
+ if (!this.available)
62
+ return [];
63
+ try {
64
+ const all = [];
65
+ const files = readdirSync(this.basePath).filter((f) => f.endsWith(".jsonl"));
66
+ for (const file of files) {
67
+ const content = readFileSync(resolve(this.basePath, file), "utf-8");
68
+ for (const line of content.split("\n").filter(Boolean)) {
69
+ try {
70
+ all.push(JSON.parse(line));
71
+ }
72
+ catch {
73
+ continue;
74
+ }
75
+ }
76
+ }
77
+ const q = query.toLowerCase().trim();
78
+ const results = all.filter(e => e.content && e.content.toLowerCase().includes(q));
79
+ return results.sort((a, b) => b.ts - a.ts).slice(0, limit);
80
+ }
81
+ catch {
82
+ return [];
83
+ }
84
+ }
85
+ buildContextBlock(sessionId) {
86
+ if (!this.available)
87
+ return "";
88
+ try {
89
+ const path = resolve(this.basePath, `${sessionId}.jsonl`);
90
+ if (!existsSync(path))
91
+ return "";
92
+ const lines = readFileSync(path, "utf-8").split("\n").filter(Boolean);
93
+ if (lines.length < 3)
94
+ return "";
95
+
96
+ const entries = lines.slice(-20).map(l => { try {
97
+ return JSON.parse(l);
98
+ }
99
+ catch {
100
+ return null;
101
+ } }).filter(Boolean);
102
+ if (entries.length < 2)
103
+ return "";
104
+ const recent = entries.slice(-6);
105
+ const summaries = recent.map(e => `[${e.role}]: ${e.content.slice(0, 150)}`);
106
+ return `\n\n[RECENT MEMORY]\n${summaries.join("\n")}\n`;
107
+ }
108
+ catch {
109
+ return "";
110
+ }
111
+ }
90
112
  }
91
113
  export const memoryStore = new MemoryStore();
92
- //# sourceMappingURL=MemoryStore.js.map
@@ -7,10 +7,11 @@ export interface ContextPressure {
7
7
  turboReady: boolean;
8
8
  }
9
9
  export declare class SessionManager {
10
- private messages;
11
- private systemPrompt;
12
- private maxContextTokens;
10
+ private head;
11
+ private tail;
12
+ private messageCount;
13
13
  private _cachedChars;
14
+ private systemPrompt;
14
15
  setSystemPrompt(prompt: string): void;
15
16
  getSystemPrompt(): string;
16
17
  addMessage(role: string, content: string): void;
@@ -21,5 +22,5 @@ export declare class SessionManager {
21
22
  getContextPressure(): ContextPressure;
22
23
  clearMessages(): void;
23
24
  getMessageCount(): number;
25
+ dispose(): void;
24
26
  }
25
- //# sourceMappingURL=SessionManager.d.ts.map
@@ -1,63 +1,84 @@
1
- /**
2
- * SessionManager manages conversation session state, context pressure tracking.
3
- */
1
+
2
+ const MAX_CONTEXT_CHARS = 128_000 * 4;
3
+ const MAX_MESSAGES = 500;
4
4
  export class SessionManager {
5
- messages = [];
6
- systemPrompt = "";
7
- maxContextTokens = 128_000;
8
- _cachedChars = 0;
9
- setSystemPrompt(prompt) {
10
- this.systemPrompt = prompt;
11
- }
12
- getSystemPrompt() {
13
- return this.systemPrompt;
14
- }
15
- addMessage(role, content) {
16
- this.messages.push({ role, content });
17
- this._cachedChars += content.length + role.length + 10;
18
- }
19
- getMessages() {
20
- // Estimate: 1 token ≈ 4 chars
21
- const maxChars = this.maxContextTokens * 4;
22
- // Fast path: if total is under limit, return all
23
- if (this._cachedChars <= maxChars) {
24
- return [...this.messages];
25
- }
26
- // Slow path: walk backwards until we hit the limit
27
- let total = 0;
28
- const result = [];
29
- for (let i = this.messages.length - 1; i >= 0; i--) {
30
- const msg = this.messages[i];
31
- const size = msg.content.length + msg.role.length + 10;
32
- if (total + size > maxChars)
33
- break;
34
- total += size;
35
- result.unshift(msg);
36
- }
37
- return result;
38
- }
39
- getContextPressure() {
40
- const totalChars = this._cachedChars || this.messages.reduce((sum, m) => sum + m.content.length + m.role.length + 10, 0);
41
- const maxChars = this.maxContextTokens * 4;
42
- const pct = Math.min(100, Math.round((totalChars / maxChars) * 100));
43
- let level = "green";
44
- if (pct > 90)
45
- level = "critical";
46
- else if (pct > 75)
47
- level = "red";
48
- else if (pct > 50)
49
- level = "yellow";
50
- return {
51
- pct,
52
- level,
53
- turboReady: pct < 70,
54
- };
55
- }
56
- clearMessages() {
57
- this.messages = [];
58
- }
59
- getMessageCount() {
60
- return this.messages.length;
61
- }
62
- }
63
- //# sourceMappingURL=SessionManager.js.map
5
+ head = null;
6
+ tail = null;
7
+ messageCount = 0;
8
+ _cachedChars = 0;
9
+ systemPrompt = "";
10
+ setSystemPrompt(prompt) {
11
+ this.systemPrompt = prompt;
12
+ }
13
+ getSystemPrompt() {
14
+ return this.systemPrompt;
15
+ }
16
+ addMessage(role, content) {
17
+ const charSize = content.length + role.length + 10;
18
+ const node = { role, content, charSize, next: null };
19
+ if (this.tail) {
20
+ this.tail.next = node;
21
+ }
22
+ else {
23
+ this.head = node;
24
+ }
25
+ this.tail = node;
26
+ this.messageCount++;
27
+ this._cachedChars += charSize;
28
+
29
+ while (this.messageCount > MAX_MESSAGES && this.head) {
30
+ this._cachedChars -= this.head.charSize;
31
+ this.head = this.head.next;
32
+ this.messageCount--;
33
+ }
34
+
35
+ while (this._cachedChars > MAX_CONTEXT_CHARS && this.head && this.head !== this.tail) {
36
+ this._cachedChars -= this.head.charSize;
37
+ this.head = this.head.next;
38
+ this.messageCount--;
39
+ }
40
+ }
41
+ getMessages() {
42
+ const result = [];
43
+ let node = this.head;
44
+ while (node) {
45
+ result.push({ role: node.role, content: node.content });
46
+ node = node.next;
47
+ }
48
+ return result;
49
+ }
50
+ getContextPressure() {
51
+ const totalChars = this._cachedChars;
52
+ const maxChars = 128_000 * 4;
53
+ const pct = Math.min(100, Math.round((totalChars / maxChars) * 100));
54
+ let level = "green";
55
+ if (pct > 90)
56
+ level = "critical";
57
+ else if (pct > 75)
58
+ level = "red";
59
+ else if (pct > 50)
60
+ level = "yellow";
61
+ return {
62
+ pct,
63
+ level,
64
+ turboReady: pct < 70,
65
+ };
66
+ }
67
+ clearMessages() {
68
+ this.head = null;
69
+ this.tail = null;
70
+ this.messageCount = 0;
71
+ this._cachedChars = 0;
72
+ }
73
+ getMessageCount() {
74
+ return this.messageCount;
75
+ }
76
+
77
+ dispose() {
78
+ this.head = null;
79
+ this.tail = null;
80
+ this.messageCount = 0;
81
+ this._cachedChars = 0;
82
+ this.systemPrompt = "";
83
+ }
84
+ }
@@ -42,4 +42,3 @@ export declare class SessionStore {
42
42
  private generateTitle;
43
43
  }
44
44
  export declare const sessionStore: SessionStore;
45
- //# sourceMappingURL=SessionStore.d.ts.map