@usejarvis/brain 0.1.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.
Files changed (266) hide show
  1. package/LICENSE +153 -0
  2. package/README.md +278 -0
  3. package/bin/jarvis.ts +413 -0
  4. package/package.json +74 -0
  5. package/scripts/ensure-bun.cjs +8 -0
  6. package/src/actions/README.md +421 -0
  7. package/src/actions/app-control/desktop-controller.test.ts +26 -0
  8. package/src/actions/app-control/desktop-controller.ts +438 -0
  9. package/src/actions/app-control/interface.ts +64 -0
  10. package/src/actions/app-control/linux.ts +273 -0
  11. package/src/actions/app-control/macos.ts +54 -0
  12. package/src/actions/app-control/sidecar-launcher.test.ts +23 -0
  13. package/src/actions/app-control/sidecar-launcher.ts +286 -0
  14. package/src/actions/app-control/windows.ts +44 -0
  15. package/src/actions/browser/cdp.ts +138 -0
  16. package/src/actions/browser/chrome-launcher.ts +252 -0
  17. package/src/actions/browser/session.ts +437 -0
  18. package/src/actions/browser/stealth.ts +49 -0
  19. package/src/actions/index.ts +20 -0
  20. package/src/actions/terminal/executor.ts +157 -0
  21. package/src/actions/terminal/wsl-bridge.ts +126 -0
  22. package/src/actions/test.ts +93 -0
  23. package/src/actions/tools/agents.ts +321 -0
  24. package/src/actions/tools/builtin.ts +846 -0
  25. package/src/actions/tools/commitments.ts +192 -0
  26. package/src/actions/tools/content.ts +217 -0
  27. package/src/actions/tools/delegate.ts +147 -0
  28. package/src/actions/tools/desktop.test.ts +55 -0
  29. package/src/actions/tools/desktop.ts +305 -0
  30. package/src/actions/tools/goals.ts +376 -0
  31. package/src/actions/tools/local-tools-guard.ts +20 -0
  32. package/src/actions/tools/registry.ts +171 -0
  33. package/src/actions/tools/research.ts +111 -0
  34. package/src/actions/tools/sidecar-list.ts +57 -0
  35. package/src/actions/tools/sidecar-route.ts +105 -0
  36. package/src/actions/tools/workflows.ts +216 -0
  37. package/src/agents/agent.ts +132 -0
  38. package/src/agents/delegation.ts +107 -0
  39. package/src/agents/hierarchy.ts +113 -0
  40. package/src/agents/index.ts +19 -0
  41. package/src/agents/messaging.ts +125 -0
  42. package/src/agents/orchestrator.ts +576 -0
  43. package/src/agents/role-discovery.ts +61 -0
  44. package/src/agents/sub-agent-runner.ts +307 -0
  45. package/src/agents/task-manager.ts +151 -0
  46. package/src/authority/approval-delivery.ts +59 -0
  47. package/src/authority/approval.ts +196 -0
  48. package/src/authority/audit.ts +158 -0
  49. package/src/authority/authority.test.ts +519 -0
  50. package/src/authority/deferred-executor.ts +103 -0
  51. package/src/authority/emergency.ts +66 -0
  52. package/src/authority/engine.ts +297 -0
  53. package/src/authority/index.ts +12 -0
  54. package/src/authority/learning.ts +111 -0
  55. package/src/authority/tool-action-map.ts +74 -0
  56. package/src/awareness/analytics.ts +466 -0
  57. package/src/awareness/awareness.test.ts +332 -0
  58. package/src/awareness/capture-engine.ts +305 -0
  59. package/src/awareness/context-graph.ts +130 -0
  60. package/src/awareness/context-tracker.ts +349 -0
  61. package/src/awareness/index.ts +25 -0
  62. package/src/awareness/intelligence.ts +321 -0
  63. package/src/awareness/ocr-engine.ts +88 -0
  64. package/src/awareness/service.ts +528 -0
  65. package/src/awareness/struggle-detector.ts +342 -0
  66. package/src/awareness/suggestion-engine.ts +476 -0
  67. package/src/awareness/types.ts +201 -0
  68. package/src/cli/autostart.ts +241 -0
  69. package/src/cli/deps.ts +449 -0
  70. package/src/cli/doctor.ts +230 -0
  71. package/src/cli/helpers.ts +401 -0
  72. package/src/cli/onboard.ts +580 -0
  73. package/src/comms/README.md +329 -0
  74. package/src/comms/auth-error.html +48 -0
  75. package/src/comms/channels/discord.ts +228 -0
  76. package/src/comms/channels/signal.ts +56 -0
  77. package/src/comms/channels/telegram.ts +316 -0
  78. package/src/comms/channels/whatsapp.ts +60 -0
  79. package/src/comms/channels.test.ts +173 -0
  80. package/src/comms/desktop-notify.ts +114 -0
  81. package/src/comms/example.ts +129 -0
  82. package/src/comms/index.ts +129 -0
  83. package/src/comms/streaming.ts +142 -0
  84. package/src/comms/voice.test.ts +152 -0
  85. package/src/comms/voice.ts +291 -0
  86. package/src/comms/websocket.test.ts +409 -0
  87. package/src/comms/websocket.ts +473 -0
  88. package/src/config/README.md +387 -0
  89. package/src/config/index.ts +6 -0
  90. package/src/config/loader.test.ts +137 -0
  91. package/src/config/loader.ts +142 -0
  92. package/src/config/types.ts +260 -0
  93. package/src/daemon/README.md +232 -0
  94. package/src/daemon/agent-service-interface.ts +9 -0
  95. package/src/daemon/agent-service.ts +600 -0
  96. package/src/daemon/api-routes.ts +2119 -0
  97. package/src/daemon/background-agent-service.ts +396 -0
  98. package/src/daemon/background-agent.test.ts +78 -0
  99. package/src/daemon/channel-service.ts +201 -0
  100. package/src/daemon/commitment-executor.ts +297 -0
  101. package/src/daemon/event-classifier.ts +239 -0
  102. package/src/daemon/event-coalescer.ts +123 -0
  103. package/src/daemon/event-reactor.ts +214 -0
  104. package/src/daemon/health.ts +220 -0
  105. package/src/daemon/index.ts +1004 -0
  106. package/src/daemon/llm-settings.ts +316 -0
  107. package/src/daemon/observer-service.ts +150 -0
  108. package/src/daemon/pid.ts +98 -0
  109. package/src/daemon/research-queue.ts +155 -0
  110. package/src/daemon/services.ts +175 -0
  111. package/src/daemon/ws-service.ts +788 -0
  112. package/src/goals/accountability.ts +240 -0
  113. package/src/goals/awareness-bridge.ts +185 -0
  114. package/src/goals/estimator.ts +185 -0
  115. package/src/goals/events.ts +28 -0
  116. package/src/goals/goals.test.ts +400 -0
  117. package/src/goals/integration.test.ts +329 -0
  118. package/src/goals/nl-builder.test.ts +220 -0
  119. package/src/goals/nl-builder.ts +256 -0
  120. package/src/goals/rhythm.test.ts +177 -0
  121. package/src/goals/rhythm.ts +275 -0
  122. package/src/goals/service.test.ts +135 -0
  123. package/src/goals/service.ts +348 -0
  124. package/src/goals/types.ts +106 -0
  125. package/src/goals/workflow-bridge.ts +96 -0
  126. package/src/integrations/google-api.ts +134 -0
  127. package/src/integrations/google-auth.ts +175 -0
  128. package/src/llm/README.md +291 -0
  129. package/src/llm/anthropic.ts +386 -0
  130. package/src/llm/gemini.ts +371 -0
  131. package/src/llm/index.ts +19 -0
  132. package/src/llm/manager.ts +153 -0
  133. package/src/llm/ollama.ts +307 -0
  134. package/src/llm/openai.ts +350 -0
  135. package/src/llm/provider.test.ts +231 -0
  136. package/src/llm/provider.ts +60 -0
  137. package/src/llm/test.ts +87 -0
  138. package/src/observers/README.md +278 -0
  139. package/src/observers/calendar.ts +113 -0
  140. package/src/observers/clipboard.ts +136 -0
  141. package/src/observers/email.ts +109 -0
  142. package/src/observers/example.ts +58 -0
  143. package/src/observers/file-watcher.ts +124 -0
  144. package/src/observers/index.ts +159 -0
  145. package/src/observers/notifications.ts +197 -0
  146. package/src/observers/observers.test.ts +203 -0
  147. package/src/observers/processes.ts +225 -0
  148. package/src/personality/README.md +61 -0
  149. package/src/personality/adapter.ts +196 -0
  150. package/src/personality/index.ts +20 -0
  151. package/src/personality/learner.ts +209 -0
  152. package/src/personality/model.ts +132 -0
  153. package/src/personality/personality.test.ts +236 -0
  154. package/src/roles/README.md +252 -0
  155. package/src/roles/authority.ts +119 -0
  156. package/src/roles/example-usage.ts +198 -0
  157. package/src/roles/index.ts +42 -0
  158. package/src/roles/loader.ts +143 -0
  159. package/src/roles/prompt-builder.ts +194 -0
  160. package/src/roles/test-multi.ts +102 -0
  161. package/src/roles/test-role.yaml +77 -0
  162. package/src/roles/test-utils.ts +93 -0
  163. package/src/roles/test.ts +106 -0
  164. package/src/roles/tool-guide.ts +190 -0
  165. package/src/roles/types.ts +36 -0
  166. package/src/roles/utils.ts +200 -0
  167. package/src/scripts/google-setup.ts +168 -0
  168. package/src/sidecar/connection.ts +179 -0
  169. package/src/sidecar/index.ts +6 -0
  170. package/src/sidecar/manager.ts +542 -0
  171. package/src/sidecar/protocol.ts +85 -0
  172. package/src/sidecar/rpc.ts +161 -0
  173. package/src/sidecar/scheduler.ts +136 -0
  174. package/src/sidecar/types.ts +112 -0
  175. package/src/sidecar/validator.ts +144 -0
  176. package/src/vault/README.md +110 -0
  177. package/src/vault/awareness.ts +341 -0
  178. package/src/vault/commitments.ts +299 -0
  179. package/src/vault/content-pipeline.ts +260 -0
  180. package/src/vault/conversations.ts +173 -0
  181. package/src/vault/entities.ts +180 -0
  182. package/src/vault/extractor.test.ts +356 -0
  183. package/src/vault/extractor.ts +345 -0
  184. package/src/vault/facts.ts +190 -0
  185. package/src/vault/goals.ts +477 -0
  186. package/src/vault/index.ts +87 -0
  187. package/src/vault/keychain.ts +99 -0
  188. package/src/vault/observations.ts +115 -0
  189. package/src/vault/relationships.ts +178 -0
  190. package/src/vault/retrieval.test.ts +126 -0
  191. package/src/vault/retrieval.ts +227 -0
  192. package/src/vault/schema.ts +658 -0
  193. package/src/vault/settings.ts +38 -0
  194. package/src/vault/vectors.ts +92 -0
  195. package/src/vault/workflows.ts +403 -0
  196. package/src/workflows/auto-suggest.ts +290 -0
  197. package/src/workflows/engine.ts +366 -0
  198. package/src/workflows/events.ts +24 -0
  199. package/src/workflows/executor.ts +207 -0
  200. package/src/workflows/nl-builder.ts +198 -0
  201. package/src/workflows/nodes/actions/agent-task.ts +73 -0
  202. package/src/workflows/nodes/actions/calendar-action.ts +85 -0
  203. package/src/workflows/nodes/actions/code-execution.ts +73 -0
  204. package/src/workflows/nodes/actions/discord.ts +77 -0
  205. package/src/workflows/nodes/actions/file-write.ts +73 -0
  206. package/src/workflows/nodes/actions/gmail.ts +69 -0
  207. package/src/workflows/nodes/actions/http-request.ts +117 -0
  208. package/src/workflows/nodes/actions/notification.ts +85 -0
  209. package/src/workflows/nodes/actions/run-tool.ts +55 -0
  210. package/src/workflows/nodes/actions/send-message.ts +82 -0
  211. package/src/workflows/nodes/actions/shell-command.ts +76 -0
  212. package/src/workflows/nodes/actions/telegram.ts +60 -0
  213. package/src/workflows/nodes/builtin.ts +119 -0
  214. package/src/workflows/nodes/error/error-handler.ts +37 -0
  215. package/src/workflows/nodes/error/fallback.ts +47 -0
  216. package/src/workflows/nodes/error/retry.ts +82 -0
  217. package/src/workflows/nodes/logic/delay.ts +42 -0
  218. package/src/workflows/nodes/logic/if-else.ts +41 -0
  219. package/src/workflows/nodes/logic/loop.ts +90 -0
  220. package/src/workflows/nodes/logic/merge.ts +38 -0
  221. package/src/workflows/nodes/logic/race.ts +40 -0
  222. package/src/workflows/nodes/logic/switch.ts +59 -0
  223. package/src/workflows/nodes/logic/template-render.ts +53 -0
  224. package/src/workflows/nodes/logic/variable-get.ts +37 -0
  225. package/src/workflows/nodes/logic/variable-set.ts +59 -0
  226. package/src/workflows/nodes/registry.ts +99 -0
  227. package/src/workflows/nodes/transform/aggregate.ts +99 -0
  228. package/src/workflows/nodes/transform/csv-parse.ts +70 -0
  229. package/src/workflows/nodes/transform/json-parse.ts +63 -0
  230. package/src/workflows/nodes/transform/map-filter.ts +84 -0
  231. package/src/workflows/nodes/transform/regex-match.ts +89 -0
  232. package/src/workflows/nodes/triggers/calendar.ts +33 -0
  233. package/src/workflows/nodes/triggers/clipboard.ts +32 -0
  234. package/src/workflows/nodes/triggers/cron.ts +40 -0
  235. package/src/workflows/nodes/triggers/email.ts +40 -0
  236. package/src/workflows/nodes/triggers/file-change.ts +45 -0
  237. package/src/workflows/nodes/triggers/git.ts +46 -0
  238. package/src/workflows/nodes/triggers/manual.ts +23 -0
  239. package/src/workflows/nodes/triggers/poll.ts +81 -0
  240. package/src/workflows/nodes/triggers/process.ts +44 -0
  241. package/src/workflows/nodes/triggers/screen-event.ts +37 -0
  242. package/src/workflows/nodes/triggers/webhook.ts +39 -0
  243. package/src/workflows/safe-eval.ts +139 -0
  244. package/src/workflows/template.ts +118 -0
  245. package/src/workflows/triggers/cron.ts +311 -0
  246. package/src/workflows/triggers/manager.ts +285 -0
  247. package/src/workflows/triggers/observer-bridge.ts +172 -0
  248. package/src/workflows/triggers/poller.ts +201 -0
  249. package/src/workflows/triggers/screen-condition.ts +218 -0
  250. package/src/workflows/triggers/triggers.test.ts +740 -0
  251. package/src/workflows/triggers/webhook.ts +191 -0
  252. package/src/workflows/types.ts +133 -0
  253. package/src/workflows/variables.ts +72 -0
  254. package/src/workflows/workflows.test.ts +383 -0
  255. package/src/workflows/yaml.ts +104 -0
  256. package/ui/dist/index-j75njzc1.css +1199 -0
  257. package/ui/dist/index-p2zh407q.js +80603 -0
  258. package/ui/dist/index.html +13 -0
  259. package/ui/public/openwakeword/models/embedding_model.onnx +0 -0
  260. package/ui/public/openwakeword/models/hey_jarvis_v0.1.onnx +0 -0
  261. package/ui/public/openwakeword/models/melspectrogram.onnx +0 -0
  262. package/ui/public/openwakeword/models/silero_vad.onnx +0 -0
  263. package/ui/public/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
  264. package/ui/public/ort/ort-wasm-simd-threaded.jsep.wasm +0 -0
  265. package/ui/public/ort/ort-wasm-simd-threaded.mjs +59 -0
  266. package/ui/public/ort/ort-wasm-simd-threaded.wasm +0 -0
@@ -0,0 +1,132 @@
1
+ import type { RoleDefinition } from '../roles/types.ts';
2
+ import type { LLMMessage } from '../llm/provider.ts';
3
+
4
+ export type AgentStatus = 'active' | 'idle' | 'terminated';
5
+
6
+ export type AuthorityBounds = {
7
+ max_authority_level: number;
8
+ allowed_tools: string[];
9
+ denied_tools: string[];
10
+ max_token_budget: number;
11
+ can_spawn_children: boolean;
12
+ };
13
+
14
+ export type Agent = {
15
+ id: string;
16
+ role: RoleDefinition;
17
+ parent_id: string | null;
18
+ status: AgentStatus;
19
+ session_id: string;
20
+ current_task: string | null;
21
+ authority: AuthorityBounds;
22
+ memory_scope: string[];
23
+ created_at: number;
24
+ };
25
+
26
+ /**
27
+ * Default authority bounds for an agent
28
+ */
29
+ function getDefaultAuthority(role: RoleDefinition): AuthorityBounds {
30
+ return {
31
+ max_authority_level: role.authority_level,
32
+ allowed_tools: role.tools,
33
+ denied_tools: [],
34
+ max_token_budget: 100000,
35
+ can_spawn_children: role.sub_roles.length > 0,
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Merge custom authority bounds with defaults
41
+ */
42
+ function mergeAuthority(
43
+ defaultAuth: AuthorityBounds,
44
+ custom?: Partial<AuthorityBounds>
45
+ ): AuthorityBounds {
46
+ if (!custom) return defaultAuth;
47
+
48
+ return {
49
+ max_authority_level: custom.max_authority_level ?? defaultAuth.max_authority_level,
50
+ allowed_tools: custom.allowed_tools ?? defaultAuth.allowed_tools,
51
+ denied_tools: custom.denied_tools ?? defaultAuth.denied_tools,
52
+ max_token_budget: custom.max_token_budget ?? defaultAuth.max_token_budget,
53
+ can_spawn_children: custom.can_spawn_children ?? defaultAuth.can_spawn_children,
54
+ };
55
+ }
56
+
57
+ export class AgentInstance {
58
+ public readonly agent: Agent;
59
+ private messageHistory: LLMMessage[];
60
+
61
+ constructor(
62
+ role: RoleDefinition,
63
+ opts?: {
64
+ parent_id?: string;
65
+ authority?: Partial<AuthorityBounds>;
66
+ memory_scope?: string[];
67
+ }
68
+ ) {
69
+ const defaultAuth = getDefaultAuthority(role);
70
+ const authority = mergeAuthority(defaultAuth, opts?.authority);
71
+
72
+ this.agent = {
73
+ id: crypto.randomUUID(),
74
+ role,
75
+ parent_id: opts?.parent_id ?? null,
76
+ status: 'active',
77
+ session_id: crypto.randomUUID(),
78
+ current_task: null,
79
+ authority,
80
+ memory_scope: opts?.memory_scope ?? [],
81
+ created_at: Date.now(),
82
+ };
83
+
84
+ this.messageHistory = [];
85
+ }
86
+
87
+ get id(): string {
88
+ return this.agent.id;
89
+ }
90
+
91
+ get status(): AgentStatus {
92
+ return this.agent.status;
93
+ }
94
+
95
+ setTask(taskDescription: string): void {
96
+ this.agent.current_task = taskDescription;
97
+ }
98
+
99
+ clearTask(): void {
100
+ this.agent.current_task = null;
101
+ }
102
+
103
+ addMessage(role: 'user' | 'assistant' | 'system', content: string): void {
104
+ this.messageHistory.push({ role, content });
105
+ }
106
+
107
+ getMessages(): LLMMessage[] {
108
+ return [...this.messageHistory];
109
+ }
110
+
111
+ terminate(): void {
112
+ this.agent.status = 'terminated';
113
+ this.clearTask();
114
+ }
115
+
116
+ activate(): void {
117
+ if (this.agent.status !== 'terminated') {
118
+ this.agent.status = 'active';
119
+ }
120
+ }
121
+
122
+ idle(): void {
123
+ if (this.agent.status !== 'terminated') {
124
+ this.agent.status = 'idle';
125
+ this.clearTask();
126
+ }
127
+ }
128
+
129
+ toJSON(): Agent {
130
+ return { ...this.agent };
131
+ }
132
+ }
@@ -0,0 +1,107 @@
1
+ import type { AgentInstance } from './agent.ts';
2
+ import type { Commitment } from '../vault/commitments.ts';
3
+ import { createCommitment } from '../vault/commitments.ts';
4
+ import { sendMessage, type MessagePriority } from './messaging.ts';
5
+
6
+ export type DelegationResult = {
7
+ success: boolean;
8
+ agent_id: string;
9
+ commitment_id: string;
10
+ message?: string;
11
+ };
12
+
13
+ /**
14
+ * Delegate a task from parent to child agent
15
+ */
16
+ export function delegateTask(
17
+ parent: AgentInstance,
18
+ child: AgentInstance,
19
+ task: {
20
+ what: string;
21
+ context: string;
22
+ priority?: 'low' | 'normal' | 'high' | 'critical';
23
+ deadline?: number;
24
+ }
25
+ ): DelegationResult {
26
+ // Verify parent-child relationship
27
+ if (child.agent.parent_id !== parent.id) {
28
+ return {
29
+ success: false,
30
+ agent_id: child.id,
31
+ commitment_id: '',
32
+ message: 'Agent is not a child of the parent agent',
33
+ };
34
+ }
35
+
36
+ // Verify parent has authority to spawn children
37
+ if (!parent.agent.authority.can_spawn_children) {
38
+ return {
39
+ success: false,
40
+ agent_id: child.id,
41
+ commitment_id: '',
42
+ message: 'Parent agent does not have authority to delegate tasks',
43
+ };
44
+ }
45
+
46
+ // Create a commitment for the child agent
47
+ const commitment = createCommitment(task.what, {
48
+ context: task.context,
49
+ priority: task.priority ?? 'normal',
50
+ when_due: task.deadline,
51
+ assigned_to: child.id,
52
+ created_from: parent.id,
53
+ });
54
+
55
+ // Send a task message to the child
56
+ const message = sendMessage(parent.id, child.id, 'task', task.what, {
57
+ priority: (task.priority === 'critical' ? 'urgent' : task.priority ?? 'normal') as MessagePriority,
58
+ requires_response: true,
59
+ deadline: task.deadline,
60
+ });
61
+
62
+ // Set the task on the child agent
63
+ child.setTask(task.what);
64
+
65
+ return {
66
+ success: true,
67
+ agent_id: child.id,
68
+ commitment_id: commitment.id,
69
+ message: `Task delegated successfully (message: ${message.id})`,
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Report task completion back to parent
75
+ */
76
+ export function reportCompletion(
77
+ child: AgentInstance,
78
+ parent: AgentInstance,
79
+ result: {
80
+ success: boolean;
81
+ summary: string;
82
+ details?: string;
83
+ }
84
+ ): void {
85
+ // Verify parent-child relationship
86
+ if (child.agent.parent_id !== parent.id) {
87
+ throw new Error('Agent is not a child of the specified parent');
88
+ }
89
+
90
+ // Build report content
91
+ const content = JSON.stringify({
92
+ task: child.agent.current_task,
93
+ success: result.success,
94
+ summary: result.summary,
95
+ details: result.details,
96
+ });
97
+
98
+ // Send a report message to the parent
99
+ sendMessage(child.id, parent.id, 'report', content, {
100
+ priority: result.success ? 'normal' : 'high',
101
+ requires_response: false,
102
+ });
103
+
104
+ // Clear the child's current task
105
+ child.clearTask();
106
+ child.idle();
107
+ }
@@ -0,0 +1,113 @@
1
+ import type { AgentInstance } from './agent.ts';
2
+
3
+ export type AgentTreeNode = {
4
+ agent: AgentInstance;
5
+ children: AgentTreeNode[];
6
+ };
7
+
8
+ export class AgentHierarchy {
9
+ private agents: Map<string, AgentInstance>;
10
+ private children: Map<string, Set<string>>; // parent_id -> child_ids
11
+
12
+ constructor() {
13
+ this.agents = new Map();
14
+ this.children = new Map();
15
+ }
16
+
17
+ addAgent(agent: AgentInstance): void {
18
+ this.agents.set(agent.id, agent);
19
+
20
+ // Track parent-child relationship
21
+ const parentId = agent.agent.parent_id;
22
+ if (parentId) {
23
+ if (!this.children.has(parentId)) {
24
+ this.children.set(parentId, new Set());
25
+ }
26
+ this.children.get(parentId)!.add(agent.id);
27
+ }
28
+ }
29
+
30
+ removeAgent(agentId: string): void {
31
+ const agent = this.agents.get(agentId);
32
+ if (!agent) return;
33
+
34
+ // Recursively remove all children first
35
+ const childIds = this.children.get(agentId);
36
+ if (childIds) {
37
+ for (const childId of Array.from(childIds)) {
38
+ this.removeAgent(childId);
39
+ }
40
+ this.children.delete(agentId);
41
+ }
42
+
43
+ // Remove from parent's children set
44
+ const parentId = agent.agent.parent_id;
45
+ if (parentId) {
46
+ const siblings = this.children.get(parentId);
47
+ if (siblings) {
48
+ siblings.delete(agentId);
49
+ }
50
+ }
51
+
52
+ // Remove the agent
53
+ this.agents.delete(agentId);
54
+ }
55
+
56
+ getAgent(agentId: string): AgentInstance | undefined {
57
+ return this.agents.get(agentId);
58
+ }
59
+
60
+ getChildren(agentId: string): AgentInstance[] {
61
+ const childIds = this.children.get(agentId);
62
+ if (!childIds) return [];
63
+
64
+ return Array.from(childIds)
65
+ .map((id) => this.agents.get(id))
66
+ .filter((agent): agent is AgentInstance => agent !== undefined);
67
+ }
68
+
69
+ getParent(agentId: string): AgentInstance | undefined {
70
+ const agent = this.agents.get(agentId);
71
+ if (!agent?.agent.parent_id) return undefined;
72
+
73
+ return this.agents.get(agent.agent.parent_id);
74
+ }
75
+
76
+ getPrimary(): AgentInstance | undefined {
77
+ // Find the agent with no parent
78
+ for (const agent of this.agents.values()) {
79
+ if (agent.agent.parent_id === null) {
80
+ return agent;
81
+ }
82
+ }
83
+ return undefined;
84
+ }
85
+
86
+ getAllAgents(): AgentInstance[] {
87
+ return Array.from(this.agents.values());
88
+ }
89
+
90
+ getActiveAgents(): AgentInstance[] {
91
+ return this.getAllAgents().filter((agent) => agent.status === 'active');
92
+ }
93
+
94
+ /**
95
+ * Get the full tree structure for display
96
+ */
97
+ getTree(): AgentTreeNode {
98
+ const primary = this.getPrimary();
99
+ if (!primary) {
100
+ throw new Error('No primary agent found in hierarchy');
101
+ }
102
+
103
+ return this.buildTreeNode(primary);
104
+ }
105
+
106
+ private buildTreeNode(agent: AgentInstance): AgentTreeNode {
107
+ const children = this.getChildren(agent.id);
108
+ return {
109
+ agent,
110
+ children: children.map((child) => this.buildTreeNode(child)),
111
+ };
112
+ }
113
+ }
@@ -0,0 +1,19 @@
1
+ // Agent lifecycle
2
+ export { AgentInstance } from './agent.ts';
3
+ export type { Agent, AgentStatus, AuthorityBounds } from './agent.ts';
4
+
5
+ // Inter-agent communication
6
+ export { sendMessage, getMessages, getPendingMessages } from './messaging.ts';
7
+ export type { AgentMessage, MessageType, MessagePriority } from './messaging.ts';
8
+
9
+ // Task delegation
10
+ export { delegateTask, reportCompletion } from './delegation.ts';
11
+ export type { DelegationResult } from './delegation.ts';
12
+
13
+ // Hierarchy management
14
+ export { AgentHierarchy } from './hierarchy.ts';
15
+ export type { AgentTreeNode } from './hierarchy.ts';
16
+
17
+ // Main orchestrator
18
+ export { AgentOrchestrator } from './orchestrator.ts';
19
+ export type { LLMManager } from '../llm/manager.ts';
@@ -0,0 +1,125 @@
1
+ import { getDb, generateId } from '../vault/schema.ts';
2
+
3
+ export type MessageType = 'task' | 'report' | 'question' | 'escalation';
4
+ export type MessagePriority = 'low' | 'normal' | 'high' | 'urgent';
5
+
6
+ export type AgentMessage = {
7
+ id: string;
8
+ from_agent: string;
9
+ to_agent: string;
10
+ type: MessageType;
11
+ content: string;
12
+ priority: MessagePriority;
13
+ requires_response: boolean;
14
+ deadline: number | null;
15
+ created_at: number;
16
+ };
17
+
18
+ type MessageRow = {
19
+ id: string;
20
+ from_agent: string;
21
+ to_agent: string;
22
+ type: MessageType;
23
+ content: string;
24
+ priority: MessagePriority;
25
+ requires_response: number;
26
+ deadline: number | null;
27
+ created_at: number;
28
+ };
29
+
30
+ /**
31
+ * Convert database row to AgentMessage
32
+ */
33
+ function parseMessage(row: MessageRow): AgentMessage {
34
+ return {
35
+ ...row,
36
+ requires_response: row.requires_response === 1,
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Send a message between agents (persisted to SQLite)
42
+ */
43
+ export function sendMessage(
44
+ from: string,
45
+ to: string,
46
+ type: MessageType,
47
+ content: string,
48
+ opts?: {
49
+ priority?: MessagePriority;
50
+ requires_response?: boolean;
51
+ deadline?: number;
52
+ }
53
+ ): AgentMessage {
54
+ const db = getDb();
55
+ const id = generateId();
56
+ const now = Date.now();
57
+ const priority = opts?.priority ?? 'normal';
58
+ const requiresResponse = opts?.requires_response ?? false;
59
+ const deadline = opts?.deadline ?? null;
60
+
61
+ const stmt = db.prepare(
62
+ 'INSERT INTO agent_messages (id, from_agent, to_agent, type, content, priority, requires_response, deadline, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'
63
+ );
64
+
65
+ stmt.run(
66
+ id,
67
+ from,
68
+ to,
69
+ type,
70
+ content,
71
+ priority,
72
+ requiresResponse ? 1 : 0,
73
+ deadline,
74
+ now
75
+ );
76
+
77
+ return {
78
+ id,
79
+ from_agent: from,
80
+ to_agent: to,
81
+ type,
82
+ content,
83
+ priority,
84
+ requires_response: requiresResponse,
85
+ deadline,
86
+ created_at: now,
87
+ };
88
+ }
89
+
90
+ /**
91
+ * Get messages for an agent
92
+ */
93
+ export function getMessages(
94
+ agentId: string,
95
+ opts?: {
96
+ type?: MessageType;
97
+ limit?: number;
98
+ }
99
+ ): AgentMessage[] {
100
+ const db = getDb();
101
+ const conditions: string[] = ['to_agent = ?'];
102
+ const params: unknown[] = [agentId];
103
+
104
+ if (opts?.type) {
105
+ conditions.push('type = ?');
106
+ params.push(opts.type);
107
+ }
108
+
109
+ const where = conditions.join(' AND ');
110
+ const limitClause = opts?.limit ? `LIMIT ${opts.limit}` : '';
111
+
112
+ const stmt = db.prepare(
113
+ `SELECT * FROM agent_messages WHERE ${where} ORDER BY created_at DESC ${limitClause}`
114
+ );
115
+
116
+ const rows = stmt.all(...params as string[]) as MessageRow[];
117
+ return rows.map(parseMessage);
118
+ }
119
+
120
+ /**
121
+ * Get unread/pending messages (all messages for now - could add read tracking)
122
+ */
123
+ export function getPendingMessages(agentId: string): AgentMessage[] {
124
+ return getMessages(agentId);
125
+ }