@adhd/agent-mcp 2.0.0 → 2.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 (299) hide show
  1. package/AGENTS.md +236 -0
  2. package/CHANGELOG.md +115 -0
  3. package/LICENSE +21 -0
  4. package/README.md +201 -0
  5. package/docs/architecture-and-security.md +405 -0
  6. package/docs/marketing/.catalog/capabilities.md +143 -0
  7. package/docs/marketing/.catalog/consumer.md +111 -0
  8. package/docs/marketing/.catalog/distribution.md +223 -0
  9. package/docs/marketing/.catalog/doc-conformance.md +237 -0
  10. package/docs/marketing/.catalog/doc-ops.md +98 -0
  11. package/docs/marketing/.catalog/metrics.md +119 -0
  12. package/docs/marketing/.catalog/required-tooling.md +224 -0
  13. package/docs/marketing/.catalog/review.md +164 -0
  14. package/docs/provider-call-audit.md +254 -0
  15. package/llms.txt +133 -0
  16. package/package.json +31 -50
  17. package/src/__tests__/integration/harness.d.ts +871 -39
  18. package/src/__tests__/integration/harness.d.ts.map +1 -1
  19. package/src/__tests__/integration/harness.js +93 -87
  20. package/src/__tests__/integration/harness.js.map +1 -1
  21. package/src/__tests__/integration/scripted-provider.d.ts +1 -2
  22. package/src/__tests__/integration/scripted-provider.d.ts.map +1 -1
  23. package/src/__tests__/integration/scripted-provider.js +1 -3
  24. package/src/__tests__/integration/scripted-provider.js.map +1 -1
  25. package/src/config.d.ts +6 -69
  26. package/src/config.d.ts.map +1 -1
  27. package/src/config.js +1 -50
  28. package/src/config.js.map +1 -1
  29. package/src/db/client.d.ts +1516 -2
  30. package/src/db/client.d.ts.map +1 -1
  31. package/src/db/client.js +4 -2
  32. package/src/db/client.js.map +1 -1
  33. package/src/db/migrate-runner.d.ts +0 -28
  34. package/src/db/migrate-runner.d.ts.map +1 -1
  35. package/src/db/migrate-runner.js +0 -24
  36. package/src/db/migrate-runner.js.map +1 -1
  37. package/src/db/migrate.d.ts +0 -7
  38. package/src/db/migrate.d.ts.map +1 -1
  39. package/src/db/migrate.js +0 -7
  40. package/src/db/migrate.js.map +1 -1
  41. package/src/db/schema.d.ts +0 -1260
  42. package/src/db/schema.d.ts.map +1 -1
  43. package/src/db/schema.js +2 -179
  44. package/src/db/schema.js.map +1 -1
  45. package/src/index.d.ts +4 -27
  46. package/src/index.d.ts.map +1 -1
  47. package/src/index.js +43 -114
  48. package/src/index.js.map +1 -1
  49. package/src/logger.d.ts +0 -8
  50. package/src/logger.d.ts.map +1 -1
  51. package/src/logger.js +1 -12
  52. package/src/logger.js.map +1 -1
  53. package/src/scripts/agent-mcp-tail.d.ts +3 -0
  54. package/src/scripts/agent-mcp-tail.d.ts.map +1 -0
  55. package/src/scripts/agent-mcp-tail.js +227 -0
  56. package/src/scripts/agent-mcp-tail.js.map +1 -0
  57. package/src/server.d.ts +13 -34
  58. package/src/server.d.ts.map +1 -1
  59. package/src/server.js +234 -326
  60. package/src/server.js.map +1 -1
  61. package/src/store/agent-store.d.ts +3 -16
  62. package/src/store/agent-store.d.ts.map +1 -1
  63. package/src/store/agent-store.js +38 -41
  64. package/src/store/agent-store.js.map +1 -1
  65. package/src/streaming/chat-gateway.d.ts +17 -0
  66. package/src/streaming/chat-gateway.d.ts.map +1 -0
  67. package/src/streaming/chat-gateway.js +336 -0
  68. package/src/streaming/chat-gateway.js.map +1 -0
  69. package/src/streaming/event-bus.d.ts +4 -0
  70. package/src/streaming/event-bus.d.ts.map +1 -1
  71. package/src/streaming/event-bus.js +14 -1
  72. package/src/streaming/event-bus.js.map +1 -1
  73. package/src/streaming/sse-server.d.ts +3 -14
  74. package/src/streaming/sse-server.d.ts.map +1 -1
  75. package/src/streaming/sse-server.js +37 -37
  76. package/src/streaming/sse-server.js.map +1 -1
  77. package/src/utils/load-env.d.ts +0 -14
  78. package/src/utils/load-env.d.ts.map +1 -1
  79. package/src/utils/load-env.js +0 -18
  80. package/src/utils/load-env.js.map +1 -1
  81. package/drizzle/0000_nifty_sasquatch.sql +0 -55
  82. package/drizzle/0001_task_usage.sql +0 -16
  83. package/drizzle/0002_lumpy_silver_centurion.sql +0 -2
  84. package/drizzle/0003_nifty_shriek.sql +0 -2
  85. package/drizzle/0004_brief_shocker.sql +0 -4
  86. package/drizzle/0005_clear_lenny_balinger.sql +0 -25
  87. package/drizzle/0006_composed_prompts_cache.sql +0 -24
  88. package/drizzle/meta/0000_snapshot.json +0 -387
  89. package/drizzle/meta/0001_snapshot.json +0 -495
  90. package/drizzle/meta/0002_snapshot.json +0 -509
  91. package/drizzle/meta/0003_snapshot.json +0 -523
  92. package/drizzle/meta/0004_snapshot.json +0 -551
  93. package/drizzle/meta/0005_snapshot.json +0 -545
  94. package/drizzle/meta/0006_snapshot.json +0 -651
  95. package/drizzle/meta/_journal.json +0 -55
  96. package/src/clients/http-client.d.ts +0 -24
  97. package/src/clients/http-client.d.ts.map +0 -1
  98. package/src/clients/http-client.js +0 -98
  99. package/src/clients/http-client.js.map +0 -1
  100. package/src/clients/in-process.d.ts +0 -27
  101. package/src/clients/in-process.d.ts.map +0 -1
  102. package/src/clients/in-process.js +0 -37
  103. package/src/clients/in-process.js.map +0 -1
  104. package/src/clients/index.d.ts +0 -7
  105. package/src/clients/index.d.ts.map +0 -1
  106. package/src/clients/index.js +0 -5
  107. package/src/clients/index.js.map +0 -1
  108. package/src/clients/registry.d.ts +0 -54
  109. package/src/clients/registry.d.ts.map +0 -1
  110. package/src/clients/registry.js +0 -164
  111. package/src/clients/registry.js.map +0 -1
  112. package/src/clients/stdio-client.d.ts +0 -16
  113. package/src/clients/stdio-client.d.ts.map +0 -1
  114. package/src/clients/stdio-client.js +0 -97
  115. package/src/clients/stdio-client.js.map +0 -1
  116. package/src/clients/tool-naming.d.ts +0 -44
  117. package/src/clients/tool-naming.d.ts.map +0 -1
  118. package/src/clients/tool-naming.js +0 -65
  119. package/src/clients/tool-naming.js.map +0 -1
  120. package/src/clients/types.d.ts +0 -18
  121. package/src/clients/types.d.ts.map +0 -1
  122. package/src/clients/types.js +0 -2
  123. package/src/clients/types.js.map +0 -1
  124. package/src/engine/dag-engine.d.ts +0 -62
  125. package/src/engine/dag-engine.d.ts.map +0 -1
  126. package/src/engine/dag-engine.js +0 -158
  127. package/src/engine/dag-engine.js.map +0 -1
  128. package/src/engine/hooks.d.ts +0 -24
  129. package/src/engine/hooks.d.ts.map +0 -1
  130. package/src/engine/hooks.js +0 -50
  131. package/src/engine/hooks.js.map +0 -1
  132. package/src/engine/orchestrator.d.ts +0 -40
  133. package/src/engine/orchestrator.d.ts.map +0 -1
  134. package/src/engine/orchestrator.js +0 -507
  135. package/src/engine/orchestrator.js.map +0 -1
  136. package/src/engine/policy.d.ts +0 -66
  137. package/src/engine/policy.d.ts.map +0 -1
  138. package/src/engine/policy.js +0 -112
  139. package/src/engine/policy.js.map +0 -1
  140. package/src/engine/prompt-resolver.d.ts +0 -89
  141. package/src/engine/prompt-resolver.d.ts.map +0 -1
  142. package/src/engine/prompt-resolver.js +0 -96
  143. package/src/engine/prompt-resolver.js.map +0 -1
  144. package/src/engine/queue.d.ts +0 -29
  145. package/src/engine/queue.d.ts.map +0 -1
  146. package/src/engine/queue.js +0 -56
  147. package/src/engine/queue.js.map +0 -1
  148. package/src/plugins/index.d.ts +0 -2
  149. package/src/plugins/index.d.ts.map +0 -1
  150. package/src/plugins/index.js +0 -2
  151. package/src/plugins/index.js.map +0 -1
  152. package/src/plugins/loader.d.ts +0 -65
  153. package/src/plugins/loader.d.ts.map +0 -1
  154. package/src/plugins/loader.js +0 -222
  155. package/src/plugins/loader.js.map +0 -1
  156. package/src/plugins/usage-plugin.d.ts +0 -27
  157. package/src/plugins/usage-plugin.d.ts.map +0 -1
  158. package/src/plugins/usage-plugin.js +0 -148
  159. package/src/plugins/usage-plugin.js.map +0 -1
  160. package/src/providers/anthropic.d.ts +0 -13
  161. package/src/providers/anthropic.d.ts.map +0 -1
  162. package/src/providers/anthropic.js +0 -260
  163. package/src/providers/anthropic.js.map +0 -1
  164. package/src/providers/claudecli.d.ts +0 -153
  165. package/src/providers/claudecli.d.ts.map +0 -1
  166. package/src/providers/claudecli.js +0 -510
  167. package/src/providers/claudecli.js.map +0 -1
  168. package/src/providers/factory.d.ts +0 -10
  169. package/src/providers/factory.d.ts.map +0 -1
  170. package/src/providers/factory.js +0 -24
  171. package/src/providers/factory.js.map +0 -1
  172. package/src/providers/index.d.ts +0 -6
  173. package/src/providers/index.d.ts.map +0 -1
  174. package/src/providers/index.js +0 -5
  175. package/src/providers/index.js.map +0 -1
  176. package/src/providers/openai.d.ts +0 -14
  177. package/src/providers/openai.d.ts.map +0 -1
  178. package/src/providers/openai.js +0 -162
  179. package/src/providers/openai.js.map +0 -1
  180. package/src/providers/types.d.ts +0 -36
  181. package/src/providers/types.d.ts.map +0 -1
  182. package/src/providers/types.js +0 -2
  183. package/src/providers/types.js.map +0 -1
  184. package/src/store/composed-prompt-store.d.ts +0 -24
  185. package/src/store/composed-prompt-store.d.ts.map +0 -1
  186. package/src/store/composed-prompt-store.js +0 -75
  187. package/src/store/composed-prompt-store.js.map +0 -1
  188. package/src/store/index.d.ts +0 -5
  189. package/src/store/index.d.ts.map +0 -1
  190. package/src/store/index.js +0 -5
  191. package/src/store/index.js.map +0 -1
  192. package/src/store/session-store.d.ts +0 -45
  193. package/src/store/session-store.d.ts.map +0 -1
  194. package/src/store/session-store.js +0 -197
  195. package/src/store/session-store.js.map +0 -1
  196. package/src/store/task-store.d.ts +0 -55
  197. package/src/store/task-store.d.ts.map +0 -1
  198. package/src/store/task-store.js +0 -186
  199. package/src/store/task-store.js.map +0 -1
  200. package/src/tools/agent-crud.d.ts +0 -15
  201. package/src/tools/agent-crud.d.ts.map +0 -1
  202. package/src/tools/agent-crud.js +0 -32
  203. package/src/tools/agent-crud.js.map +0 -1
  204. package/src/tools/session.d.ts +0 -33
  205. package/src/tools/session.d.ts.map +0 -1
  206. package/src/tools/session.js +0 -73
  207. package/src/tools/session.js.map +0 -1
  208. package/src/tools/task.d.ts +0 -86
  209. package/src/tools/task.d.ts.map +0 -1
  210. package/src/tools/task.js +0 -406
  211. package/src/tools/task.js.map +0 -1
  212. package/src/tools/usage.d.ts +0 -60
  213. package/src/tools/usage.d.ts.map +0 -1
  214. package/src/tools/usage.js +0 -174
  215. package/src/tools/usage.js.map +0 -1
  216. package/src/types/agent.d.ts +0 -2
  217. package/src/types/agent.d.ts.map +0 -1
  218. package/src/types/agent.js +0 -3
  219. package/src/types/agent.js.map +0 -1
  220. package/src/types/execution.d.ts +0 -2
  221. package/src/types/execution.d.ts.map +0 -1
  222. package/src/types/execution.js +0 -3
  223. package/src/types/execution.js.map +0 -1
  224. package/src/types/index.d.ts +0 -2
  225. package/src/types/index.d.ts.map +0 -1
  226. package/src/types/index.js +0 -2
  227. package/src/types/index.js.map +0 -1
  228. package/src/types/mcp.d.ts +0 -2
  229. package/src/types/mcp.d.ts.map +0 -1
  230. package/src/types/mcp.js +0 -3
  231. package/src/types/mcp.js.map +0 -1
  232. package/src/types/message.d.ts +0 -2
  233. package/src/types/message.d.ts.map +0 -1
  234. package/src/types/message.js +0 -3
  235. package/src/types/message.js.map +0 -1
  236. package/src/types/session.d.ts +0 -2
  237. package/src/types/session.d.ts.map +0 -1
  238. package/src/types/session.js +0 -3
  239. package/src/types/session.js.map +0 -1
  240. package/src/types/task.d.ts +0 -2
  241. package/src/types/task.d.ts.map +0 -1
  242. package/src/types/task.js +0 -3
  243. package/src/types/task.js.map +0 -1
  244. package/src/utils/ids.d.ts +0 -2
  245. package/src/utils/ids.d.ts.map +0 -1
  246. package/src/utils/ids.js +0 -5
  247. package/src/utils/ids.js.map +0 -1
  248. package/src/utils/logger.d.ts +0 -2
  249. package/src/utils/logger.d.ts.map +0 -1
  250. package/src/utils/logger.js +0 -5
  251. package/src/utils/logger.js.map +0 -1
  252. package/src/utils/timestamps.d.ts +0 -2
  253. package/src/utils/timestamps.d.ts.map +0 -1
  254. package/src/utils/timestamps.js +0 -4
  255. package/src/utils/timestamps.js.map +0 -1
  256. package/src/validation/agent.d.ts +0 -400
  257. package/src/validation/agent.d.ts.map +0 -1
  258. package/src/validation/agent.js +0 -251
  259. package/src/validation/agent.js.map +0 -1
  260. package/src/validation/agents.d.ts +0 -2
  261. package/src/validation/agents.d.ts.map +0 -1
  262. package/src/validation/agents.js +0 -3
  263. package/src/validation/agents.js.map +0 -1
  264. package/src/validation/errors.d.ts +0 -32
  265. package/src/validation/errors.d.ts.map +0 -1
  266. package/src/validation/errors.js +0 -42
  267. package/src/validation/errors.js.map +0 -1
  268. package/src/validation/execution.d.ts +0 -86
  269. package/src/validation/execution.d.ts.map +0 -1
  270. package/src/validation/execution.js +0 -28
  271. package/src/validation/execution.js.map +0 -1
  272. package/src/validation/index.d.ts +0 -9
  273. package/src/validation/index.d.ts.map +0 -1
  274. package/src/validation/index.js +0 -9
  275. package/src/validation/index.js.map +0 -1
  276. package/src/validation/mcp.d.ts +0 -42
  277. package/src/validation/mcp.d.ts.map +0 -1
  278. package/src/validation/mcp.js +0 -28
  279. package/src/validation/mcp.js.map +0 -1
  280. package/src/validation/message.d.ts +0 -43
  281. package/src/validation/message.d.ts.map +0 -1
  282. package/src/validation/message.js +0 -23
  283. package/src/validation/message.js.map +0 -1
  284. package/src/validation/session.d.ts +0 -49
  285. package/src/validation/session.d.ts.map +0 -1
  286. package/src/validation/session.js +0 -34
  287. package/src/validation/session.js.map +0 -1
  288. package/src/validation/task.d.ts +0 -146
  289. package/src/validation/task.d.ts.map +0 -1
  290. package/src/validation/task.js +0 -95
  291. package/src/validation/task.js.map +0 -1
  292. package/src/validation/tasks.d.ts +0 -2
  293. package/src/validation/tasks.d.ts.map +0 -1
  294. package/src/validation/tasks.js +0 -3
  295. package/src/validation/tasks.js.map +0 -1
  296. package/src/validation/usage.d.ts +0 -89
  297. package/src/validation/usage.d.ts.map +0 -1
  298. package/src/validation/usage.js +0 -98
  299. package/src/validation/usage.js.map +0 -1
package/src/tools/task.js DELETED
@@ -1,406 +0,0 @@
1
- import { logger } from "../logger.js";
2
- import { config } from "../config.js";
3
- import { resolveHitl } from "../engine/orchestrator.js";
4
- import { createProvider } from "../providers/factory.js";
5
- import { McpClientRegistry as McpClientRegistryCtor } from "../clients/registry.js";
6
- import { ToolError } from "../validation/errors.js";
7
- import { generateId } from "../utils/ids.js";
8
- import { nowIso } from "../utils/timestamps.js";
9
- import { buildTaskUsageReport } from "./usage.js";
10
- /**
11
- * One-shot ephemeral execution: runs a prompt against an agent without creating a
12
- * session row or persisting any messages. Persists a tasks row + task_events +
13
- * task_usage so the run is observable via task_list / result / metrics.
14
- */
15
- async function runEphemeralTask(input, deps, callerContext) {
16
- const agentDefinition = deps.agentStore.read(input.agent_name);
17
- const taskId = generateId();
18
- // Use a synthetic session ID only as an in-memory identifier for message
19
- // threading within this run — it is never written to the DB.
20
- const ephemeralSessionId = generateId();
21
- const rootTaskId = callerContext
22
- ? (callerContext.rootTaskId ?? callerContext.taskId)
23
- : undefined;
24
- // Persist the tasks row so this run is observable (task_list, result tool, metrics).
25
- // session_id is NULL and is_ephemeral=1 — no sessions row is created.
26
- deps.taskStore.create({
27
- id: taskId,
28
- sessionId: null,
29
- isEphemeral: true,
30
- prompt: input.prompt,
31
- parentTaskId: callerContext?.taskId,
32
- recursionDepth: (callerContext?.recursionDepth ?? -1) + 1,
33
- });
34
- const executionContext = {
35
- taskId,
36
- sessionId: ephemeralSessionId,
37
- agentName: agentDefinition.name,
38
- agentDefinition,
39
- callingAgentName: callerContext?.agentName,
40
- parentTaskId: callerContext?.taskId,
41
- rootTaskId: rootTaskId ?? undefined,
42
- recursionDepth: (callerContext?.recursionDepth ?? -1) + 1,
43
- toolCallCount: 0,
44
- };
45
- const provider = createProvider(agentDefinition.provider, agentDefinition.mcpServers);
46
- const userMessage = {
47
- id: generateId(),
48
- sessionId: ephemeralSessionId,
49
- role: "user",
50
- content: input.prompt,
51
- createdAt: nowIso(),
52
- };
53
- const messages = agentDefinition.systemPrompt
54
- ? [
55
- {
56
- id: generateId(),
57
- sessionId: ephemeralSessionId,
58
- role: "system",
59
- content: agentDefinition.systemPrompt,
60
- createdAt: nowIso(),
61
- },
62
- userMessage,
63
- ]
64
- : [userMessage];
65
- // No messages are persisted — noopSessionStore swallows appendMessage calls.
66
- const noopSessionStore = {
67
- // eslint-disable-next-line @typescript-eslint/no-empty-function
68
- appendMessage: async () => { },
69
- };
70
- const registry = new McpClientRegistryCtor(
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- agentDefinition.mcpServers, deps.selfUrl, deps.inProcessDescriptors, deps.inProcessHandler, executionContext);
73
- const controller = new AbortController();
74
- deps.taskStore.registerCancellation(taskId, controller);
75
- try {
76
- await deps.orchestrator.run({
77
- executionContext,
78
- messages,
79
- registry,
80
- provider,
81
- policy: deps.policy,
82
- taskStore: deps.taskStore, // REAL store — events + status persisted
83
- sessionStore: noopSessionStore,
84
- signal: controller.signal,
85
- taskId,
86
- hooks: deps.hooks,
87
- isEphemeral: true, // forbids request_human_input
88
- });
89
- }
90
- catch {
91
- // Orchestrator already updated status via deps.taskStore
92
- }
93
- finally {
94
- deps.taskStore.unregisterCancellation(taskId);
95
- }
96
- const finalTask = deps.taskStore.read(taskId);
97
- const usage = buildTaskUsageReport(deps.db, taskId);
98
- return {
99
- task_id: taskId,
100
- status: finalTask.status,
101
- result: finalTask.result,
102
- usage,
103
- };
104
- }
105
- /**
106
- * `task` tool — runs a prompt against a session's agent (session mode) or runs a
107
- * one-shot ephemeral task without persisting any context (agent_name mode).
108
- *
109
- * Session mode mandatory order (per plan Gap 17):
110
- * 1. Validate session exists and is active
111
- * 2. Load snapshotted AgentDefinition
112
- * 3. Create Task row
113
- * 4. Build ExecutionContext
114
- * 5. Create AbortController
115
- * 6. Register cancellation
116
- * 7. Build provider
117
- * 8. Build per-task registry
118
- * 9. Run orchestrator (background or sync)
119
- */
120
- export async function taskTool(input, deps, callerContext) {
121
- if ("agent_name" in input) {
122
- return runEphemeralTask(input, deps, callerContext);
123
- }
124
- // 1. Validate session
125
- const session = deps.sessionStore.read(input.session_id);
126
- if (session.status !== "active") {
127
- throw new ToolError("SESSION_CLOSED", `Session '${input.session_id}' is closed`);
128
- }
129
- // 2. Load snapshotted agent definition
130
- const agentDefinition = deps.sessionStore.getAgentDefinition(input.session_id);
131
- // 3. Create task row
132
- // Validate no dependency cycle before inserting the row.
133
- // [inv:cycle-check-synchronous] — throws ToolError("VALIDATION_ERROR") on cycle.
134
- const dependsOn = input.depends_on ?? [];
135
- const onUpstreamFailure = input
136
- .on_upstream_failure;
137
- // Generate the id up front so the cycle check validates the SAME id that is
138
- // inserted below (TaskStore.create reuses input.id when provided).
139
- const newTaskId = generateId();
140
- if (dependsOn.length > 0) {
141
- deps.dagEngine.validateNoCycle(newTaskId, dependsOn);
142
- }
143
- const task = deps.taskStore.create({
144
- id: newTaskId,
145
- sessionId: input.session_id,
146
- prompt: input.prompt,
147
- parentTaskId: callerContext?.taskId,
148
- recursionDepth: (callerContext?.recursionDepth ?? -1) + 1,
149
- dependsOn: dependsOn.length > 0 ? dependsOn : undefined,
150
- onUpstreamFailure,
151
- });
152
- // Derive rootTaskId at creation time from the in-memory callerContext chain.
153
- // A DB walk is deliberately avoided — ephemeral tasks have no tasks row.
154
- const rootTaskId = callerContext
155
- ? (callerContext.rootTaskId ?? callerContext.taskId)
156
- : undefined;
157
- // 4. Build execution context
158
- const executionContext = {
159
- taskId: task.id,
160
- sessionId: input.session_id,
161
- agentName: agentDefinition.name,
162
- agentDefinition,
163
- callingAgentName: callerContext?.agentName,
164
- parentTaskId: callerContext?.taskId,
165
- rootTaskId: rootTaskId ?? undefined,
166
- recursionDepth: (callerContext?.recursionDepth ?? -1) + 1,
167
- toolCallCount: 0,
168
- };
169
- // 5. Create AbortController
170
- const controller = new AbortController();
171
- // 6. Register cancellation
172
- deps.taskStore.registerCancellation(task.id, controller);
173
- // 7. Build provider
174
- const provider = createProvider(agentDefinition.provider, agentDefinition.mcpServers);
175
- // Build initial messages
176
- const existingMessages = deps.sessionStore.getMessages(input.session_id);
177
- const userMessage = {
178
- id: generateId(),
179
- sessionId: input.session_id,
180
- role: "user",
181
- content: input.prompt,
182
- createdAt: nowIso(),
183
- };
184
- await deps.sessionStore.appendMessage(input.session_id, userMessage);
185
- const messages = [...existingMessages, userMessage];
186
- // Add system message if the agent has one
187
- const allMessages = agentDefinition.systemPrompt
188
- ? [
189
- {
190
- id: generateId(),
191
- sessionId: input.session_id,
192
- role: "system",
193
- content: agentDefinition.systemPrompt,
194
- createdAt: nowIso(),
195
- },
196
- ...messages,
197
- ]
198
- : messages;
199
- // 8. Build per-task registry
200
- const registry = new McpClientRegistryCtor(
201
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
- agentDefinition.mcpServers, deps.selfUrl, deps.inProcessDescriptors, deps.inProcessHandler, executionContext);
203
- // 9. Run orchestrator
204
- const runTask = async () => {
205
- try {
206
- await deps.orchestrator.run({
207
- executionContext,
208
- messages: allMessages,
209
- registry,
210
- provider,
211
- policy: deps.policy,
212
- taskStore: deps.taskStore,
213
- sessionStore: deps.sessionStore,
214
- signal: controller.signal,
215
- taskId: task.id,
216
- hooks: deps.hooks,
217
- });
218
- }
219
- finally {
220
- // [inv:dispatch-on-completion] — dispatchReady fires on every terminal
221
- // event (completed, failed, cancelled) so dependent waiting tasks are
222
- // evaluated regardless of how this task ended.
223
- await deps.dagEngine.dispatchReady(task.id);
224
- }
225
- };
226
- // Compute stream_url when streaming is requested for a backgrounded task.
227
- // A synchronous task is already complete by the time the caller gets the
228
- // response, so an SSE URL for it would only ever hit the terminal-on-connect
229
- // path and close immediately — omit it.
230
- const sseBaseUrl = config.sse.baseUrl;
231
- const streamUrl = input.stream && input.background
232
- ? `${sseBaseUrl}/tasks/${task.id}/stream`
233
- : undefined;
234
- if (input.background) {
235
- // Enqueue for background execution — return immediately
236
- deps.queue.enqueue(task.id, runTask);
237
- logger.info({ taskId: task.id, sessionId: input.session_id }, "Task enqueued for background execution");
238
- const response = {
239
- task_id: task.id,
240
- status: "pending",
241
- };
242
- if (streamUrl) {
243
- response.stream_url = streamUrl;
244
- }
245
- return response;
246
- }
247
- else {
248
- // Synchronous execution — wait for completion
249
- try {
250
- await runTask();
251
- }
252
- catch (error) {
253
- // Orchestrator already updated the task status
254
- // Return the current task state
255
- }
256
- const finalTask = deps.taskStore.read(task.id);
257
- const usage = buildTaskUsageReport(deps.db, finalTask.id);
258
- const response = {
259
- task_id: finalTask.id,
260
- status: finalTask.status,
261
- result: finalTask.result,
262
- usage,
263
- };
264
- if (streamUrl) {
265
- response.stream_url = streamUrl;
266
- }
267
- return response;
268
- }
269
- }
270
- /**
271
- * Re-enqueue an existing task row that is already in "pending" status.
272
- *
273
- * Called by DagEngine.dispatchFn (built in index.ts) when a waiting task
274
- * transitions to pending after all its dependencies complete. The task row
275
- * already exists in the DB — this function only builds the runtime context
276
- * (executionContext, messages, provider, registry) and enqueues it.
277
- *
278
- * Also used on server startup to re-enqueue tasks orphaned by a crash between
279
- * DagEngine's DB update and queue.enqueue().
280
- */
281
- export async function enqueueExistingTask(taskId, deps) {
282
- const task = deps.taskStore.read(taskId);
283
- // Ephemeral tasks have no session row and no in-memory provider context.
284
- // If the process restarted, the orchestrator context is gone and the task
285
- // cannot be resumed. Mark it failed so it doesn't linger as pending.
286
- if (task.isEphemeral || !task.sessionId) {
287
- logger.warn({ taskId, isEphemeral: task.isEphemeral }, "enqueueExistingTask: skipping ephemeral task — context lost on restart");
288
- try {
289
- deps.taskStore.updateStatus(taskId, "failed", {
290
- error: "Ephemeral task context lost on server restart; create a new task.",
291
- });
292
- }
293
- catch {
294
- // Already in a terminal state — ignore
295
- }
296
- return;
297
- }
298
- const session = deps.sessionStore.read(task.sessionId);
299
- if (session.status !== "active") {
300
- logger.warn({ taskId, sessionId: task.sessionId }, "enqueueExistingTask: session is not active, skipping dispatch");
301
- return;
302
- }
303
- const agentDefinition = deps.sessionStore.getAgentDefinition(task.sessionId);
304
- const executionContext = {
305
- taskId,
306
- sessionId: task.sessionId,
307
- agentName: agentDefinition.name,
308
- agentDefinition,
309
- recursionDepth: task.recursionDepth,
310
- toolCallCount: 0,
311
- inputs: task.inputs ?? undefined,
312
- };
313
- const controller = new AbortController();
314
- deps.taskStore.registerCancellation(taskId, controller);
315
- const provider = createProvider(agentDefinition.provider, agentDefinition.mcpServers);
316
- const existingMessages = deps.sessionStore.getMessages(task.sessionId);
317
- const userMessage = {
318
- id: generateId(),
319
- sessionId: task.sessionId,
320
- role: "user",
321
- content: task.prompt,
322
- createdAt: nowIso(),
323
- };
324
- const messages = [...existingMessages, userMessage];
325
- const allMessages = agentDefinition.systemPrompt
326
- ? [
327
- {
328
- id: generateId(),
329
- sessionId: task.sessionId,
330
- role: "system",
331
- content: agentDefinition.systemPrompt,
332
- createdAt: nowIso(),
333
- },
334
- ...messages,
335
- ]
336
- : messages;
337
- const registry = new McpClientRegistryCtor(
338
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
339
- agentDefinition.mcpServers, deps.selfUrl, deps.inProcessDescriptors, deps.inProcessHandler, executionContext);
340
- deps.queue.enqueue(taskId, async () => {
341
- try {
342
- await deps.orchestrator.run({
343
- executionContext,
344
- messages: allMessages,
345
- registry,
346
- provider,
347
- policy: deps.policy,
348
- taskStore: deps.taskStore,
349
- sessionStore: deps.sessionStore,
350
- signal: controller.signal,
351
- taskId,
352
- hooks: deps.hooks,
353
- });
354
- }
355
- finally {
356
- // [inv:dispatch-on-completion] — dispatchReady fires on every terminal event
357
- await deps.dagEngine.dispatchReady(taskId);
358
- }
359
- });
360
- }
361
- export function taskList(input, deps) {
362
- return deps.taskStore.list(input);
363
- }
364
- export function taskCancel(input, deps) {
365
- const task = deps.taskStore.read(input.task_id); // throws TASK_NOT_FOUND
366
- const cancellableStatuses = ["pending", "running", "awaiting_input"];
367
- if (!cancellableStatuses.includes(task.status)) {
368
- throw new ToolError("TASK_NOT_CANCELLABLE", `Task '${input.task_id}' has status '${task.status}' and cannot be cancelled`);
369
- }
370
- deps.taskStore.cancel(input.task_id);
371
- return { success: true };
372
- }
373
- /**
374
- * `task_resume` tool — resumes a suspended `awaiting_input` task by providing
375
- * the `userInput` that the orchestrator is waiting for.
376
- *
377
- * The caller must supply the `resumeToken` that was written to the DB when the
378
- * task was suspended. If the process restarted while the task was suspended the
379
- * in-memory resolver no longer exists; the task is auto-failed and
380
- * `TASK_NOT_RESUMABLE` is thrown so the caller knows not to retry.
381
- */
382
- export async function taskResume(input, deps) {
383
- const task = deps.taskStore.read(input.taskId); // throws TASK_NOT_FOUND
384
- if (task.status !== "awaiting_input") {
385
- throw new ToolError("VALIDATION_ERROR", `Task '${input.taskId}' is not awaiting input (status: ${task.status})`);
386
- }
387
- if (task.resumeToken !== input.resumeToken) {
388
- throw new ToolError("VALIDATION_ERROR", "Invalid resumeToken");
389
- }
390
- const resolved = resolveHitl(input.taskId, input.userInput);
391
- if (!resolved) {
392
- // Process restarted — in-memory resolver is gone. Auto-fail the task so it
393
- // doesn't remain stranded in awaiting_input with no escape path.
394
- deps.taskStore.updateStatus(input.taskId, "failed", {
395
- error: "Task could not be resumed: server restarted while task was suspended. Create a new task.",
396
- });
397
- throw new ToolError("TASK_NOT_RESUMABLE", `Task '${input.taskId}' has no active suspension (process restarted; task has been failed)`);
398
- }
399
- return { success: true, taskId: input.taskId };
400
- }
401
- export function resultTool(input, deps) {
402
- const task = deps.taskStore.read(input.task_id); // throws TASK_NOT_FOUND
403
- const usage = buildTaskUsageReport(deps.db, task.id);
404
- return { ...task, usage };
405
- }
406
- //# sourceMappingURL=task.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task.js","sourceRoot":"","sources":["../../../../../../packages/ai/agent-mcp/src/tools/task.ts"],"names":[],"mappings":"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"}
@@ -1,60 +0,0 @@
1
- import type { BetterSQLite3Database } from "drizzle-orm/better-sqlite3";
2
- import { taskUsageTable } from "../db/schema.js";
3
- import type { GroupedUsageRow, TaskUsageInput, TaskUsageReport } from "../validation/usage.js";
4
- /**
5
- * Drizzle database handle. Identical to what the stores and UsagePlugin receive.
6
- */
7
- export type Database = BetterSQLite3Database<any>;
8
- /** A single row from the `task_usage` table, as returned by drizzle select. */
9
- export type TaskUsageRow = typeof taskUsageTable.$inferSelect;
10
- export interface UsageQueryResult {
11
- rows: TaskUsageRow[];
12
- /**
13
- * Populated only when `group_by` is set in the input. Each entry aggregates
14
- * all matching tasks along the chosen dimension (agent, model, or provider).
15
- * `rows` is empty when `groups` is present.
16
- */
17
- groups?: GroupedUsageRow[];
18
- summary: {
19
- totalInputTokens: number;
20
- totalOutputTokens: number;
21
- totalToolCalls: number;
22
- totalModelCalls: number;
23
- taskCount: number;
24
- };
25
- }
26
- /**
27
- * `usage_query` tool implementation.
28
- *
29
- * Queries `task_usage` with optional filters. Every filter is optional; a bare
30
- * `{}` (or `undefined`) returns the most recent rows, capped at `limit`.
31
- *
32
- * - `task_id`: returns that row AND the full delegation subtree
33
- * (`task_id = ? OR root_task_id = ?`).
34
- * - `root_task_id`: returns the root row plus every descendant
35
- * (`task_id = ? OR root_task_id = ?`).
36
- * - `agent_name`, `since`: plain equality / lower-bound filters.
37
- * - `include_incomplete` (default false): when false, only `is_complete = 1`
38
- * rows are returned.
39
- *
40
- * Returns `{ rows: [], summary: { ...zeros, taskCount: 0 } }` when the table
41
- * is empty or nothing matches.
42
- */
43
- export declare function usageQuery(db: Database, input: TaskUsageInput): UsageQueryResult;
44
- /**
45
- * Builds a {@link TaskUsageReport} for enriching a `task` / `result` response.
46
- *
47
- * - `direct`: aggregates `task_usage WHERE task_id = ?` (this task's own model
48
- * calls only).
49
- * - `subtree`: aggregates `task_usage WHERE task_id = ? OR root_task_id = ?`
50
- * (this task plus every sub-task that recorded it as its root).
51
- * - `taskCount`: number of distinct rows folded into the subtree.
52
- *
53
- * Returns `undefined` when no `task_usage` row exists for the task — i.e. the
54
- * task ran zero model calls (still running, or cancelled before its first
55
- * model call). See `[shape:TaskUsageReport]`.
56
- *
57
- * claudecli rows are present with zero token counts and are returned as-is.
58
- */
59
- export declare function buildTaskUsageReport(db: Database, taskId: string): TaskUsageReport | undefined;
60
- //# sourceMappingURL=usage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../../../../packages/ai/agent-mcp/src/tools/usage.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,OAAO,EAAE,cAAc,EAAc,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EAEhB,MAAM,wBAAwB,CAAC;AAEhC;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;AAElD,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AA8BD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,gBAAgB,CA8FhF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,MAAM,GACb,eAAe,GAAG,SAAS,CAkB7B"}
@@ -1,174 +0,0 @@
1
- import { and, desc, eq, gte, or, sql } from "drizzle-orm";
2
- const SEVERITY = { length: 3, tool_calls: 2, stop: 1, unknown: 0 };
3
- function mostSevereStr(a, b) {
4
- if (!a && !b)
5
- return undefined;
6
- const sa = SEVERITY[a ?? ""] ?? 0;
7
- const sb = SEVERITY[b ?? ""] ?? 0;
8
- return sa >= sb ? a : b;
9
- }
10
- import { taskUsageTable, tasksTable } from "../db/schema.js";
11
- /**
12
- * Folds a set of `task_usage` rows into a single {@link UsageSummary}.
13
- *
14
- * claudecli rows carry zeros for token counts — they are summed as-is, so a
15
- * caller seeing `inputTokens === 0` must not conclude "zero tokens consumed";
16
- * it may mean the provider does not report token counts. See
17
- * `[inv:claudecli-undefined]`.
18
- */
19
- function summarise(rows) {
20
- return rows.reduce((acc, row) => ({
21
- inputTokens: acc.inputTokens + (row.inputTokens ?? 0),
22
- outputTokens: acc.outputTokens + (row.outputTokens ?? 0),
23
- modelCalls: acc.modelCalls + (row.modelCalls ?? 0),
24
- toolCallCount: acc.toolCallCount + (row.toolCallCount ?? 0),
25
- latencyMs: acc.latencyMs + (row.latencyMs ?? 0),
26
- stopReason: mostSevereStr(acc.stopReason, row.stopReason ?? undefined),
27
- }), {
28
- inputTokens: 0,
29
- outputTokens: 0,
30
- modelCalls: 0,
31
- toolCallCount: 0,
32
- latencyMs: 0,
33
- });
34
- }
35
- /**
36
- * `usage_query` tool implementation.
37
- *
38
- * Queries `task_usage` with optional filters. Every filter is optional; a bare
39
- * `{}` (or `undefined`) returns the most recent rows, capped at `limit`.
40
- *
41
- * - `task_id`: returns that row AND the full delegation subtree
42
- * (`task_id = ? OR root_task_id = ?`).
43
- * - `root_task_id`: returns the root row plus every descendant
44
- * (`task_id = ? OR root_task_id = ?`).
45
- * - `agent_name`, `since`: plain equality / lower-bound filters.
46
- * - `include_incomplete` (default false): when false, only `is_complete = 1`
47
- * rows are returned.
48
- *
49
- * Returns `{ rows: [], summary: { ...zeros, taskCount: 0 } }` when the table
50
- * is empty or nothing matches.
51
- */
52
- export function usageQuery(db, input) {
53
- const filters = [];
54
- // task_id and root_task_id both expand to a subtree match.
55
- if (input?.task_id) {
56
- const id = input.task_id;
57
- const subtree = or(eq(taskUsageTable.taskId, id), eq(taskUsageTable.rootTaskId, id));
58
- if (subtree)
59
- filters.push(subtree);
60
- }
61
- if (input?.root_task_id) {
62
- const id = input.root_task_id;
63
- const subtree = or(eq(taskUsageTable.taskId, id), eq(taskUsageTable.rootTaskId, id));
64
- if (subtree)
65
- filters.push(subtree);
66
- }
67
- if (input?.agent_name) {
68
- filters.push(eq(taskUsageTable.agentName, input.agent_name));
69
- }
70
- if (input?.since) {
71
- filters.push(gte(taskUsageTable.createdAt, input.since));
72
- }
73
- if (!input?.include_incomplete) {
74
- filters.push(eq(taskUsageTable.isComplete, 1));
75
- }
76
- const whereClause = filters.length > 0 ? and(...filters) : undefined;
77
- const limit = input?.limit ?? 50;
78
- // ── Grouped aggregation path ──────────────────────────────────────────────
79
- if (input?.group_by) {
80
- // Map the group_by enum to the actual column reference.
81
- let groupCol;
82
- if (input.group_by === "model") {
83
- groupCol = taskUsageTable.model;
84
- }
85
- else if (input.group_by === "provider") {
86
- groupCol = taskUsageTable.providerType;
87
- }
88
- else {
89
- groupCol = taskUsageTable.agentName; // "agent"
90
- }
91
- const groups = db
92
- .select({
93
- key: groupCol,
94
- taskCount: sql `count(*)`,
95
- completedCount: sql `sum(case when ${tasksTable.status} = 'completed' then 1 else 0 end)`,
96
- failedCount: sql `sum(case when ${tasksTable.status} = 'failed' then 1 else 0 end)`,
97
- cancelledCount: sql `sum(case when ${tasksTable.status} = 'cancelled' then 1 else 0 end)`,
98
- inputTokens: sql `sum(${taskUsageTable.inputTokens})`,
99
- outputTokens: sql `sum(${taskUsageTable.outputTokens})`,
100
- toolCallCount: sql `sum(${taskUsageTable.toolCallCount})`,
101
- modelCalls: sql `sum(${taskUsageTable.modelCalls})`,
102
- avgLatencyMs: sql `avg(case when ${taskUsageTable.latencyMs} > 0 then ${taskUsageTable.latencyMs} else null end)`,
103
- cacheReadTokens: sql `sum(${taskUsageTable.cacheReadTokens})`,
104
- cacheCreationTokens: sql `sum(${taskUsageTable.cacheCreationTokens})`,
105
- })
106
- .from(taskUsageTable)
107
- .leftJoin(tasksTable, eq(taskUsageTable.taskId, tasksTable.id))
108
- .where(whereClause)
109
- .groupBy(groupCol)
110
- .orderBy(desc(sql `sum(${taskUsageTable.inputTokens} + ${taskUsageTable.outputTokens})`))
111
- .limit(limit)
112
- .all();
113
- const totalInputTokens = groups.reduce((n, r) => n + r.inputTokens, 0);
114
- const totalOutputTokens = groups.reduce((n, r) => n + r.outputTokens, 0);
115
- const totalToolCalls = groups.reduce((n, r) => n + r.toolCallCount, 0);
116
- const totalModelCalls = groups.reduce((n, r) => n + r.modelCalls, 0);
117
- const taskCount = groups.reduce((n, r) => n + r.taskCount, 0);
118
- return {
119
- rows: [],
120
- groups,
121
- summary: { totalInputTokens, totalOutputTokens, totalToolCalls, totalModelCalls, taskCount },
122
- };
123
- }
124
- // ── Raw rows path (original behaviour) ───────────────────────────────────
125
- const rows = db
126
- .select()
127
- .from(taskUsageTable)
128
- .where(whereClause)
129
- .orderBy(desc(taskUsageTable.createdAt))
130
- .limit(limit)
131
- .all();
132
- return {
133
- rows,
134
- summary: {
135
- totalInputTokens: rows.reduce((n, r) => n + (r.inputTokens ?? 0), 0),
136
- totalOutputTokens: rows.reduce((n, r) => n + (r.outputTokens ?? 0), 0),
137
- totalToolCalls: rows.reduce((n, r) => n + (r.toolCallCount ?? 0), 0),
138
- totalModelCalls: rows.reduce((n, r) => n + (r.modelCalls ?? 0), 0),
139
- taskCount: rows.length,
140
- },
141
- };
142
- }
143
- /**
144
- * Builds a {@link TaskUsageReport} for enriching a `task` / `result` response.
145
- *
146
- * - `direct`: aggregates `task_usage WHERE task_id = ?` (this task's own model
147
- * calls only).
148
- * - `subtree`: aggregates `task_usage WHERE task_id = ? OR root_task_id = ?`
149
- * (this task plus every sub-task that recorded it as its root).
150
- * - `taskCount`: number of distinct rows folded into the subtree.
151
- *
152
- * Returns `undefined` when no `task_usage` row exists for the task — i.e. the
153
- * task ran zero model calls (still running, or cancelled before its first
154
- * model call). See `[shape:TaskUsageReport]`.
155
- *
156
- * claudecli rows are present with zero token counts and are returned as-is.
157
- */
158
- export function buildTaskUsageReport(db, taskId) {
159
- const subtreeRows = db
160
- .select()
161
- .from(taskUsageTable)
162
- .where(or(eq(taskUsageTable.taskId, taskId), eq(taskUsageTable.rootTaskId, taskId)))
163
- .all();
164
- if (subtreeRows.length === 0) {
165
- return undefined;
166
- }
167
- const directRows = subtreeRows.filter(row => row.taskId === taskId);
168
- return {
169
- direct: summarise(directRows),
170
- subtree: summarise(subtreeRows),
171
- taskCount: subtreeRows.length,
172
- };
173
- }
174
- //# sourceMappingURL=usage.js.map