@aiaiaichain/agent 0.1.1

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 (68) hide show
  1. package/README.md +157 -0
  2. package/bin/aiai-mcp +31 -0
  3. package/bin/aiaiaicli +60 -0
  4. package/dist/api/ExtensionAPI.d.ts +68 -0
  5. package/dist/api/ExtensionAPI.js +9 -0
  6. package/dist/api/Registry.d.ts +24 -0
  7. package/dist/api/Registry.js +58 -0
  8. package/dist/cli.d.ts +6 -0
  9. package/dist/cli.js +252 -0
  10. package/dist/core/AgentDir.d.ts +10 -0
  11. package/dist/core/AgentDir.js +74 -0
  12. package/dist/core/ChainConfig.d.ts +19 -0
  13. package/dist/core/ChainConfig.js +65 -0
  14. package/dist/core/EnvLoader.d.ts +15 -0
  15. package/dist/core/EnvLoader.js +58 -0
  16. package/dist/index.d.ts +41 -0
  17. package/dist/index.js +42 -0
  18. package/dist/loader.d.ts +11 -0
  19. package/dist/loader.js +73 -0
  20. package/dist/mcp/entry.d.ts +5 -0
  21. package/dist/mcp/entry.js +10 -0
  22. package/dist/mcp/server.d.ts +14 -0
  23. package/dist/mcp/server.js +137 -0
  24. package/dist/models/CostTracker.d.ts +38 -0
  25. package/dist/models/CostTracker.js +75 -0
  26. package/dist/models/ModelRegistry.d.ts +70 -0
  27. package/dist/models/ModelRegistry.js +163 -0
  28. package/dist/runner/AgentRunner.d.ts +54 -0
  29. package/dist/runner/AgentRunner.js +171 -0
  30. package/dist/runner/ModelClient.d.ts +30 -0
  31. package/dist/runner/ModelClient.js +84 -0
  32. package/dist/runner/SwarmRouter.d.ts +23 -0
  33. package/dist/runner/SwarmRouter.js +24 -0
  34. package/dist/runner/ToolDispatcher.d.ts +13 -0
  35. package/dist/runner/ToolDispatcher.js +34 -0
  36. package/dist/scheduler/AgentScheduler.d.ts +48 -0
  37. package/dist/scheduler/AgentScheduler.js +111 -0
  38. package/dist/session/ContextStore.d.ts +28 -0
  39. package/dist/session/ContextStore.js +85 -0
  40. package/dist/session/GoalManager.d.ts +43 -0
  41. package/dist/session/GoalManager.js +108 -0
  42. package/dist/session/MemoryStore.d.ts +27 -0
  43. package/dist/session/MemoryStore.js +92 -0
  44. package/dist/session/SessionManager.d.ts +24 -0
  45. package/dist/session/SessionManager.js +57 -0
  46. package/dist/setup/SetupWizard.d.ts +13 -0
  47. package/dist/setup/SetupWizard.js +71 -0
  48. package/dist/tools/MarketSentiment.d.ts +20 -0
  49. package/dist/tools/MarketSentiment.js +211 -0
  50. package/dist/tools/NewsSentiment.d.ts +36 -0
  51. package/dist/tools/NewsSentiment.js +141 -0
  52. package/dist/tools/PriceFeed.d.ts +85 -0
  53. package/dist/tools/PriceFeed.js +134 -0
  54. package/dist/tools/TechnicalAnalysis.d.ts +50 -0
  55. package/dist/tools/TechnicalAnalysis.js +234 -0
  56. package/dist/tui/App.d.ts +20 -0
  57. package/dist/tui/App.js +484 -0
  58. package/dist/tui/ModelSelector.d.ts +18 -0
  59. package/dist/tui/ModelSelector.js +59 -0
  60. package/dist/tui/REPL.d.ts +22 -0
  61. package/dist/tui/REPL.js +48 -0
  62. package/dist/tui/StatusBar.d.ts +14 -0
  63. package/dist/tui/StatusBar.js +13 -0
  64. package/dist/tui/theme.d.ts +27 -0
  65. package/dist/tui/theme.js +38 -0
  66. package/dist/util/safeLog.d.ts +8 -0
  67. package/dist/util/safeLog.js +38 -0
  68. package/package.json +64 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * SwarmRouter — parallel sub-agent orchestration.
3
+ * Routes tasks to appropriate model tiers for parallel execution.
4
+ */
5
+ export class SwarmRouter {
6
+ registry;
7
+ constructor(registry) {
8
+ this.registry = registry;
9
+ }
10
+ async runConcurrent(tasks, _sessionCtx) {
11
+ return Promise.all(tasks.map(t => this.runSingle(t)));
12
+ }
13
+ async runSingle(task) {
14
+ try {
15
+ // For v1, just execute the task via the available tools
16
+ // This is simplified — real parallel model calls would go through ModelClient
17
+ return { taskId: task.id, output: `[${task.tier}] ${task.prompt}` };
18
+ }
19
+ catch (e) {
20
+ return { taskId: task.id, output: "", error: e instanceof Error ? e.message : String(e) };
21
+ }
22
+ }
23
+ }
24
+ //# sourceMappingURL=SwarmRouter.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ToolDispatcher — dispatches tool calls from the AI to registered tool handlers.
3
+ */
4
+ import type { ToolDef, ToolResult } from "../api/ExtensionAPI.js";
5
+ import type { Registry } from "../api/Registry.js";
6
+ export declare class ToolDispatcher {
7
+ private registry;
8
+ constructor(registry: Registry);
9
+ dispatch(toolName: string, params: Record<string, unknown>): Promise<ToolResult>;
10
+ listTools(): ToolDef[];
11
+ getTool(name: string): ToolDef | undefined;
12
+ }
13
+ //# sourceMappingURL=ToolDispatcher.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * ToolDispatcher — dispatches tool calls from the AI to registered tool handlers.
3
+ */
4
+ export class ToolDispatcher {
5
+ registry;
6
+ constructor(registry) {
7
+ this.registry = registry;
8
+ }
9
+ async dispatch(toolName, params) {
10
+ const tool = this.registry.getTool(toolName);
11
+ if (!tool) {
12
+ return {
13
+ content: [{ type: "text", text: `Unknown tool: "${toolName}"` }],
14
+ isError: true,
15
+ };
16
+ }
17
+ try {
18
+ return await tool.execute(`invoke-${Date.now()}`, params);
19
+ }
20
+ catch (e) {
21
+ return {
22
+ content: [{ type: "text", text: `Tool "${toolName}" error: ${e instanceof Error ? e.message : String(e)}` }],
23
+ isError: true,
24
+ };
25
+ }
26
+ }
27
+ listTools() {
28
+ return this.registry.listTools();
29
+ }
30
+ getTool(name) {
31
+ return this.registry.getTool(name);
32
+ }
33
+ }
34
+ //# sourceMappingURL=ToolDispatcher.js.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * AgentScheduler — cron and price-triggered scheduled tasks.
3
+ * Persisted to ~/.aiaiai/memory/schedule.json
4
+ */
5
+ import type { ToolResult } from "../api/ExtensionAPI.js";
6
+ export interface ScheduledTask {
7
+ id: string;
8
+ name: string;
9
+ prompt: string;
10
+ cron?: string;
11
+ priceTrigger?: {
12
+ symbol: string;
13
+ above?: number;
14
+ below?: number;
15
+ };
16
+ enabled: boolean;
17
+ lastRun?: number;
18
+ createdAt: number;
19
+ }
20
+ export declare class AgentScheduler {
21
+ private tasks;
22
+ private interval;
23
+ private onTask?;
24
+ constructor();
25
+ private load;
26
+ private save;
27
+ addTask(name: string, prompt: string, intervalSeconds?: number): ScheduledTask;
28
+ removeTask(id: string): boolean;
29
+ listTasks(): ScheduledTask[];
30
+ start(onTask: (task: ScheduledTask) => void): void;
31
+ stop(): void;
32
+ addTaskParams: import("@sinclair/typebox").TObject<{
33
+ name: import("@sinclair/typebox").TString;
34
+ prompt: import("@sinclair/typebox").TString;
35
+ interval: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
36
+ }>;
37
+ listTasksParams: import("@sinclair/typebox").TObject<{
38
+ enabled_only: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
39
+ }>;
40
+ removeTaskParams: import("@sinclair/typebox").TObject<{
41
+ id: import("@sinclair/typebox").TString;
42
+ }>;
43
+ addTaskTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
44
+ listTasksTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
45
+ removeTaskTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
46
+ }
47
+ export declare const agentScheduler: AgentScheduler;
48
+ //# sourceMappingURL=AgentScheduler.d.ts.map
@@ -0,0 +1,111 @@
1
+ /**
2
+ * AgentScheduler — cron and price-triggered scheduled tasks.
3
+ * Persisted to ~/.aiaiai/memory/schedule.json
4
+ */
5
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import { Type } from "@sinclair/typebox";
8
+ import { AgentDir } from "../core/AgentDir.js";
9
+ const SCHEDULE_PATH = resolve(AgentDir.getHome(), "memory", "schedule.json");
10
+ export class AgentScheduler {
11
+ tasks = [];
12
+ interval = null;
13
+ onTask;
14
+ constructor() {
15
+ this.load();
16
+ }
17
+ load() {
18
+ try {
19
+ if (existsSync(SCHEDULE_PATH)) {
20
+ this.tasks = JSON.parse(readFileSync(SCHEDULE_PATH, "utf-8"));
21
+ }
22
+ }
23
+ catch {
24
+ this.tasks = [];
25
+ }
26
+ }
27
+ save() {
28
+ try {
29
+ writeFileSync(SCHEDULE_PATH, JSON.stringify(this.tasks, null, 2), "utf-8");
30
+ }
31
+ catch { /* non-fatal */ }
32
+ }
33
+ addTask(name, prompt, intervalSeconds) {
34
+ const task = {
35
+ id: `task-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
36
+ name,
37
+ prompt,
38
+ cron: intervalSeconds ? String(intervalSeconds) : undefined,
39
+ enabled: true,
40
+ createdAt: Date.now(),
41
+ };
42
+ this.tasks.push(task);
43
+ this.save();
44
+ return task;
45
+ }
46
+ removeTask(id) {
47
+ const idx = this.tasks.findIndex(t => t.id === id);
48
+ if (idx === -1)
49
+ return false;
50
+ this.tasks.splice(idx, 1);
51
+ this.save();
52
+ return true;
53
+ }
54
+ listTasks() {
55
+ return [...this.tasks];
56
+ }
57
+ start(onTask) {
58
+ this.onTask = onTask;
59
+ if (this.interval)
60
+ clearInterval(this.interval);
61
+ this.interval = setInterval(() => {
62
+ const now = Date.now();
63
+ for (const task of this.tasks) {
64
+ if (!task.enabled || !task.cron)
65
+ continue;
66
+ const interval = parseInt(task.cron) * 1000;
67
+ if (!task.lastRun || (now - task.lastRun) >= interval) {
68
+ task.lastRun = now;
69
+ this.save();
70
+ this.onTask?.(task);
71
+ }
72
+ }
73
+ }, 10_000); // Check every 10 seconds
74
+ }
75
+ stop() {
76
+ if (this.interval) {
77
+ clearInterval(this.interval);
78
+ this.interval = null;
79
+ }
80
+ }
81
+ // ── Tools ───────────────────────────────────────────────────────────────
82
+ addTaskParams = Type.Object({
83
+ name: Type.String({ description: "Task name" }),
84
+ prompt: Type.String({ description: "Prompt to run when task fires" }),
85
+ interval: Type.Optional(Type.Number({ description: "Run every N seconds" })),
86
+ });
87
+ listTasksParams = Type.Object({
88
+ enabled_only: Type.Optional(Type.Boolean({ default: false })),
89
+ });
90
+ removeTaskParams = Type.Object({
91
+ id: Type.String({ description: "Task ID to remove" }),
92
+ });
93
+ async addTaskTool(_id, params) {
94
+ const task = this.addTask(params.name, params.prompt, params.interval);
95
+ return { content: [{ type: "text", text: `Task "${task.name}" created (${task.id})` }] };
96
+ }
97
+ async listTasksTool(_id, params) {
98
+ const enabledOnly = params.enabled_only || false;
99
+ const tasks = enabledOnly ? this.tasks.filter(t => t.enabled) : this.tasks;
100
+ if (tasks.length === 0)
101
+ return { content: [{ type: "text", text: "No scheduled tasks." }] };
102
+ const lines = tasks.map(t => ` ${t.enabled ? "🟢" : "⏸️"} ${t.id} — ${t.name}${t.cron ? ` (every ${t.cron}s)` : ""}`);
103
+ return { content: [{ type: "text", text: `Scheduled Tasks (${tasks.length}):\n${lines.join("\n")}` }] };
104
+ }
105
+ async removeTaskTool(_id, params) {
106
+ const ok = this.removeTask(params.id);
107
+ return { content: [{ type: "text", text: ok ? `Task ${params.id} removed` : `Task ${params.id} not found` }] };
108
+ }
109
+ }
110
+ export const agentScheduler = new AgentScheduler();
111
+ //# sourceMappingURL=AgentScheduler.js.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * ContextStore — persistent task context folders.
3
+ * Allows multi-step operations to store and retrieve intermediate state.
4
+ */
5
+ import type { ToolResult } from "../api/ExtensionAPI.js";
6
+ export interface TaskContext {
7
+ taskId: string;
8
+ data: Record<string, unknown>;
9
+ createdAt: number;
10
+ updatedAt: number;
11
+ keep?: boolean;
12
+ }
13
+ export declare class ContextStore {
14
+ private basePath;
15
+ constructor();
16
+ saveTask(taskId: string, data: Record<string, unknown>): void;
17
+ readTask(taskId: string): TaskContext | null;
18
+ listTasks(): TaskContext[];
19
+ keepTask(taskId: string): boolean;
20
+ readContextParams: import("@sinclair/typebox").TObject<{
21
+ taskId: import("@sinclair/typebox").TString;
22
+ }>;
23
+ listTasksParams: import("@sinclair/typebox").TObject<{}>;
24
+ readContextTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
25
+ listTasksTool(): Promise<ToolResult>;
26
+ }
27
+ export declare const contextStore: ContextStore;
28
+ //# sourceMappingURL=ContextStore.d.ts.map
@@ -0,0 +1,85 @@
1
+ /**
2
+ * ContextStore — persistent task context folders.
3
+ * Allows multi-step operations to store and retrieve intermediate state.
4
+ */
5
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import { Type } from "@sinclair/typebox";
8
+ import { AgentDir } from "../core/AgentDir.js";
9
+ export class ContextStore {
10
+ basePath;
11
+ constructor() {
12
+ this.basePath = resolve(AgentDir.getHome(), "sessions", "tasks");
13
+ if (!existsSync(this.basePath))
14
+ mkdirSync(this.basePath, { recursive: true });
15
+ }
16
+ saveTask(taskId, data) {
17
+ const ctx = {
18
+ taskId,
19
+ data,
20
+ createdAt: Date.now(),
21
+ updatedAt: Date.now(),
22
+ };
23
+ writeFileSync(resolve(this.basePath, `${taskId}.json`), JSON.stringify(ctx, null, 2), "utf-8");
24
+ }
25
+ readTask(taskId) {
26
+ const p = resolve(this.basePath, `${taskId}.json`);
27
+ if (!existsSync(p))
28
+ return null;
29
+ try {
30
+ return JSON.parse(readFileSync(p, "utf-8"));
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ listTasks() {
37
+ if (!existsSync(this.basePath))
38
+ return [];
39
+ try {
40
+ return readdirSync(this.basePath)
41
+ .filter(f => f.endsWith(".json"))
42
+ .map(f => {
43
+ try {
44
+ return JSON.parse(readFileSync(resolve(this.basePath, f), "utf-8"));
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ })
50
+ .filter(Boolean);
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ }
56
+ keepTask(taskId) {
57
+ const ctx = this.readTask(taskId);
58
+ if (!ctx)
59
+ return false;
60
+ ctx.keep = true;
61
+ ctx.updatedAt = Date.now();
62
+ writeFileSync(resolve(this.basePath, `${taskId}.json`), JSON.stringify(ctx, null, 2), "utf-8");
63
+ return true;
64
+ }
65
+ // ── Tools ───────────────────────────────────────────────────────────────
66
+ readContextParams = Type.Object({
67
+ taskId: Type.String({ description: "Task ID from a previous multi-step operation" }),
68
+ });
69
+ listTasksParams = Type.Object({});
70
+ async readContextTool(_id, params) {
71
+ const ctx = this.readTask(params.taskId);
72
+ if (!ctx)
73
+ return { content: [{ type: "text", text: `Task "${params.taskId}" not found.` }] };
74
+ return { content: [{ type: "text", text: JSON.stringify(ctx.data, null, 2) }] };
75
+ }
76
+ async listTasksTool() {
77
+ const tasks = this.listTasks();
78
+ if (tasks.length === 0)
79
+ return { content: [{ type: "text", text: "No saved tasks." }] };
80
+ const lines = tasks.map(t => ` ${t.taskId} — ${Object.keys(t.data).length} keys (${new Date(t.updatedAt).toLocaleString()})${t.keep ? " 🔒" : ""}`);
81
+ return { content: [{ type: "text", text: `Tasks (${tasks.length}):\n${lines.join("\n")}` }] };
82
+ }
83
+ }
84
+ export const contextStore = new ContextStore();
85
+ //# sourceMappingURL=ContextStore.js.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * GoalManager — persistent cross-session goals for the agent to monitor and complete.
3
+ * Goals are stored in ~/.aiaiai/memory/goals.json
4
+ */
5
+ import type { ToolResult } from "../api/ExtensionAPI.js";
6
+ export interface Goal {
7
+ id: string;
8
+ text: string;
9
+ status: "active" | "completed";
10
+ createdAt: number;
11
+ completedAt?: number;
12
+ notes: string[];
13
+ }
14
+ export declare class GoalManager {
15
+ private goals;
16
+ constructor();
17
+ private load;
18
+ private save;
19
+ addGoal(text: string): Goal;
20
+ completeGoal(id: string): boolean;
21
+ addNote(id: string, note: string): boolean;
22
+ listGoals(status?: "active" | "completed" | "all"): Goal[];
23
+ buildContextBlock(): string;
24
+ setGoalParams: import("@sinclair/typebox").TObject<{
25
+ text: import("@sinclair/typebox").TString;
26
+ }>;
27
+ completeGoalParams: import("@sinclair/typebox").TObject<{
28
+ id: import("@sinclair/typebox").TString;
29
+ }>;
30
+ listGoalsParams: import("@sinclair/typebox").TObject<{
31
+ status: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
32
+ }>;
33
+ addGoalNoteParams: import("@sinclair/typebox").TObject<{
34
+ id: import("@sinclair/typebox").TString;
35
+ note: import("@sinclair/typebox").TString;
36
+ }>;
37
+ setGoalTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
38
+ completeGoalTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
39
+ listGoalsTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
40
+ addGoalNoteTool(_id: string, params: Record<string, unknown>): Promise<ToolResult>;
41
+ }
42
+ export declare const goalManager: GoalManager;
43
+ //# sourceMappingURL=GoalManager.d.ts.map
@@ -0,0 +1,108 @@
1
+ /**
2
+ * GoalManager — persistent cross-session goals for the agent to monitor and complete.
3
+ * Goals are stored in ~/.aiaiai/memory/goals.json
4
+ */
5
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
6
+ import { resolve } from "node:path";
7
+ import { Type } from "@sinclair/typebox";
8
+ import { AgentDir } from "../core/AgentDir.js";
9
+ const GOALS_PATH = resolve(AgentDir.getHome(), "memory", "goals.json");
10
+ 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
+ }
106
+ }
107
+ export const goalManager = new GoalManager();
108
+ //# sourceMappingURL=GoalManager.js.map
@@ -0,0 +1,27 @@
1
+ /**
2
+ * MemoryStore — persistent long-term memory for agents.
3
+ * Stored in ~/.aiaiai/memory/ as JSONL files per session.
4
+ */
5
+ export interface MemoryEntry {
6
+ id: string;
7
+ sessionId: string;
8
+ role: "user" | "assistant" | "system";
9
+ content: string;
10
+ ts: number;
11
+ }
12
+ export interface RecentSession {
13
+ sessionId: string;
14
+ lastActive: number;
15
+ summary: string;
16
+ }
17
+ export declare class MemoryStore {
18
+ private basePath;
19
+ private available;
20
+ constructor();
21
+ get isAvailable(): boolean;
22
+ save(sessionId: string, role: "user" | "assistant" | "system", content: string): void;
23
+ search(query: string, limit?: number): MemoryEntry[];
24
+ buildContextBlock(sessionId: string): string;
25
+ }
26
+ export declare const memoryStore: MemoryStore;
27
+ //# sourceMappingURL=MemoryStore.d.ts.map
@@ -0,0 +1,92 @@
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";
6
+ import { resolve } from "node:path";
7
+ import { AgentDir } from "../core/AgentDir.js";
8
+ 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
+ }
90
+ }
91
+ export const memoryStore = new MemoryStore();
92
+ //# sourceMappingURL=MemoryStore.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * SessionManager — manages conversation session state, context pressure tracking.
3
+ */
4
+ export interface ContextPressure {
5
+ pct: number;
6
+ level: "green" | "yellow" | "red" | "critical";
7
+ turboReady: boolean;
8
+ }
9
+ export declare class SessionManager {
10
+ private messages;
11
+ private systemPrompt;
12
+ private maxContextTokens;
13
+ setSystemPrompt(prompt: string): void;
14
+ getSystemPrompt(): string;
15
+ addMessage(role: string, content: string): void;
16
+ getMessages(): Array<{
17
+ role: string;
18
+ content: string;
19
+ }>;
20
+ getContextPressure(): ContextPressure;
21
+ clearMessages(): void;
22
+ getMessageCount(): number;
23
+ }
24
+ //# sourceMappingURL=SessionManager.d.ts.map