@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.
- package/AGENTS.md +236 -0
- package/CHANGELOG.md +115 -0
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/docs/architecture-and-security.md +405 -0
- package/docs/marketing/.catalog/capabilities.md +143 -0
- package/docs/marketing/.catalog/consumer.md +111 -0
- package/docs/marketing/.catalog/distribution.md +223 -0
- package/docs/marketing/.catalog/doc-conformance.md +237 -0
- package/docs/marketing/.catalog/doc-ops.md +98 -0
- package/docs/marketing/.catalog/metrics.md +119 -0
- package/docs/marketing/.catalog/required-tooling.md +224 -0
- package/docs/marketing/.catalog/review.md +164 -0
- package/docs/provider-call-audit.md +254 -0
- package/llms.txt +133 -0
- package/package.json +31 -50
- package/src/__tests__/integration/harness.d.ts +871 -39
- package/src/__tests__/integration/harness.d.ts.map +1 -1
- package/src/__tests__/integration/harness.js +93 -87
- package/src/__tests__/integration/harness.js.map +1 -1
- package/src/__tests__/integration/scripted-provider.d.ts +1 -2
- package/src/__tests__/integration/scripted-provider.d.ts.map +1 -1
- package/src/__tests__/integration/scripted-provider.js +1 -3
- package/src/__tests__/integration/scripted-provider.js.map +1 -1
- package/src/config.d.ts +6 -69
- package/src/config.d.ts.map +1 -1
- package/src/config.js +1 -50
- package/src/config.js.map +1 -1
- package/src/db/client.d.ts +1516 -2
- package/src/db/client.d.ts.map +1 -1
- package/src/db/client.js +4 -2
- package/src/db/client.js.map +1 -1
- package/src/db/migrate-runner.d.ts +0 -28
- package/src/db/migrate-runner.d.ts.map +1 -1
- package/src/db/migrate-runner.js +0 -24
- package/src/db/migrate-runner.js.map +1 -1
- package/src/db/migrate.d.ts +0 -7
- package/src/db/migrate.d.ts.map +1 -1
- package/src/db/migrate.js +0 -7
- package/src/db/migrate.js.map +1 -1
- package/src/db/schema.d.ts +0 -1260
- package/src/db/schema.d.ts.map +1 -1
- package/src/db/schema.js +2 -179
- package/src/db/schema.js.map +1 -1
- package/src/index.d.ts +4 -27
- package/src/index.d.ts.map +1 -1
- package/src/index.js +43 -114
- package/src/index.js.map +1 -1
- package/src/logger.d.ts +0 -8
- package/src/logger.d.ts.map +1 -1
- package/src/logger.js +1 -12
- package/src/logger.js.map +1 -1
- package/src/scripts/agent-mcp-tail.d.ts +3 -0
- package/src/scripts/agent-mcp-tail.d.ts.map +1 -0
- package/src/scripts/agent-mcp-tail.js +227 -0
- package/src/scripts/agent-mcp-tail.js.map +1 -0
- package/src/server.d.ts +13 -34
- package/src/server.d.ts.map +1 -1
- package/src/server.js +234 -326
- package/src/server.js.map +1 -1
- package/src/store/agent-store.d.ts +3 -16
- package/src/store/agent-store.d.ts.map +1 -1
- package/src/store/agent-store.js +38 -41
- package/src/store/agent-store.js.map +1 -1
- package/src/streaming/chat-gateway.d.ts +17 -0
- package/src/streaming/chat-gateway.d.ts.map +1 -0
- package/src/streaming/chat-gateway.js +336 -0
- package/src/streaming/chat-gateway.js.map +1 -0
- package/src/streaming/event-bus.d.ts +4 -0
- package/src/streaming/event-bus.d.ts.map +1 -1
- package/src/streaming/event-bus.js +14 -1
- package/src/streaming/event-bus.js.map +1 -1
- package/src/streaming/sse-server.d.ts +3 -14
- package/src/streaming/sse-server.d.ts.map +1 -1
- package/src/streaming/sse-server.js +37 -37
- package/src/streaming/sse-server.js.map +1 -1
- package/src/utils/load-env.d.ts +0 -14
- package/src/utils/load-env.d.ts.map +1 -1
- package/src/utils/load-env.js +0 -18
- package/src/utils/load-env.js.map +1 -1
- package/drizzle/0000_nifty_sasquatch.sql +0 -55
- package/drizzle/0001_task_usage.sql +0 -16
- package/drizzle/0002_lumpy_silver_centurion.sql +0 -2
- package/drizzle/0003_nifty_shriek.sql +0 -2
- package/drizzle/0004_brief_shocker.sql +0 -4
- package/drizzle/0005_clear_lenny_balinger.sql +0 -25
- package/drizzle/0006_composed_prompts_cache.sql +0 -24
- package/drizzle/meta/0000_snapshot.json +0 -387
- package/drizzle/meta/0001_snapshot.json +0 -495
- package/drizzle/meta/0002_snapshot.json +0 -509
- package/drizzle/meta/0003_snapshot.json +0 -523
- package/drizzle/meta/0004_snapshot.json +0 -551
- package/drizzle/meta/0005_snapshot.json +0 -545
- package/drizzle/meta/0006_snapshot.json +0 -651
- package/drizzle/meta/_journal.json +0 -55
- package/src/clients/http-client.d.ts +0 -24
- package/src/clients/http-client.d.ts.map +0 -1
- package/src/clients/http-client.js +0 -98
- package/src/clients/http-client.js.map +0 -1
- package/src/clients/in-process.d.ts +0 -27
- package/src/clients/in-process.d.ts.map +0 -1
- package/src/clients/in-process.js +0 -37
- package/src/clients/in-process.js.map +0 -1
- package/src/clients/index.d.ts +0 -7
- package/src/clients/index.d.ts.map +0 -1
- package/src/clients/index.js +0 -5
- package/src/clients/index.js.map +0 -1
- package/src/clients/registry.d.ts +0 -54
- package/src/clients/registry.d.ts.map +0 -1
- package/src/clients/registry.js +0 -164
- package/src/clients/registry.js.map +0 -1
- package/src/clients/stdio-client.d.ts +0 -16
- package/src/clients/stdio-client.d.ts.map +0 -1
- package/src/clients/stdio-client.js +0 -97
- package/src/clients/stdio-client.js.map +0 -1
- package/src/clients/tool-naming.d.ts +0 -44
- package/src/clients/tool-naming.d.ts.map +0 -1
- package/src/clients/tool-naming.js +0 -65
- package/src/clients/tool-naming.js.map +0 -1
- package/src/clients/types.d.ts +0 -18
- package/src/clients/types.d.ts.map +0 -1
- package/src/clients/types.js +0 -2
- package/src/clients/types.js.map +0 -1
- package/src/engine/dag-engine.d.ts +0 -62
- package/src/engine/dag-engine.d.ts.map +0 -1
- package/src/engine/dag-engine.js +0 -158
- package/src/engine/dag-engine.js.map +0 -1
- package/src/engine/hooks.d.ts +0 -24
- package/src/engine/hooks.d.ts.map +0 -1
- package/src/engine/hooks.js +0 -50
- package/src/engine/hooks.js.map +0 -1
- package/src/engine/orchestrator.d.ts +0 -40
- package/src/engine/orchestrator.d.ts.map +0 -1
- package/src/engine/orchestrator.js +0 -507
- package/src/engine/orchestrator.js.map +0 -1
- package/src/engine/policy.d.ts +0 -66
- package/src/engine/policy.d.ts.map +0 -1
- package/src/engine/policy.js +0 -112
- package/src/engine/policy.js.map +0 -1
- package/src/engine/prompt-resolver.d.ts +0 -89
- package/src/engine/prompt-resolver.d.ts.map +0 -1
- package/src/engine/prompt-resolver.js +0 -96
- package/src/engine/prompt-resolver.js.map +0 -1
- package/src/engine/queue.d.ts +0 -29
- package/src/engine/queue.d.ts.map +0 -1
- package/src/engine/queue.js +0 -56
- package/src/engine/queue.js.map +0 -1
- package/src/plugins/index.d.ts +0 -2
- package/src/plugins/index.d.ts.map +0 -1
- package/src/plugins/index.js +0 -2
- package/src/plugins/index.js.map +0 -1
- package/src/plugins/loader.d.ts +0 -65
- package/src/plugins/loader.d.ts.map +0 -1
- package/src/plugins/loader.js +0 -222
- package/src/plugins/loader.js.map +0 -1
- package/src/plugins/usage-plugin.d.ts +0 -27
- package/src/plugins/usage-plugin.d.ts.map +0 -1
- package/src/plugins/usage-plugin.js +0 -148
- package/src/plugins/usage-plugin.js.map +0 -1
- package/src/providers/anthropic.d.ts +0 -13
- package/src/providers/anthropic.d.ts.map +0 -1
- package/src/providers/anthropic.js +0 -260
- package/src/providers/anthropic.js.map +0 -1
- package/src/providers/claudecli.d.ts +0 -153
- package/src/providers/claudecli.d.ts.map +0 -1
- package/src/providers/claudecli.js +0 -510
- package/src/providers/claudecli.js.map +0 -1
- package/src/providers/factory.d.ts +0 -10
- package/src/providers/factory.d.ts.map +0 -1
- package/src/providers/factory.js +0 -24
- package/src/providers/factory.js.map +0 -1
- package/src/providers/index.d.ts +0 -6
- package/src/providers/index.d.ts.map +0 -1
- package/src/providers/index.js +0 -5
- package/src/providers/index.js.map +0 -1
- package/src/providers/openai.d.ts +0 -14
- package/src/providers/openai.d.ts.map +0 -1
- package/src/providers/openai.js +0 -162
- package/src/providers/openai.js.map +0 -1
- package/src/providers/types.d.ts +0 -36
- package/src/providers/types.d.ts.map +0 -1
- package/src/providers/types.js +0 -2
- package/src/providers/types.js.map +0 -1
- package/src/store/composed-prompt-store.d.ts +0 -24
- package/src/store/composed-prompt-store.d.ts.map +0 -1
- package/src/store/composed-prompt-store.js +0 -75
- package/src/store/composed-prompt-store.js.map +0 -1
- package/src/store/index.d.ts +0 -5
- package/src/store/index.d.ts.map +0 -1
- package/src/store/index.js +0 -5
- package/src/store/index.js.map +0 -1
- package/src/store/session-store.d.ts +0 -45
- package/src/store/session-store.d.ts.map +0 -1
- package/src/store/session-store.js +0 -197
- package/src/store/session-store.js.map +0 -1
- package/src/store/task-store.d.ts +0 -55
- package/src/store/task-store.d.ts.map +0 -1
- package/src/store/task-store.js +0 -186
- package/src/store/task-store.js.map +0 -1
- package/src/tools/agent-crud.d.ts +0 -15
- package/src/tools/agent-crud.d.ts.map +0 -1
- package/src/tools/agent-crud.js +0 -32
- package/src/tools/agent-crud.js.map +0 -1
- package/src/tools/session.d.ts +0 -33
- package/src/tools/session.d.ts.map +0 -1
- package/src/tools/session.js +0 -73
- package/src/tools/session.js.map +0 -1
- package/src/tools/task.d.ts +0 -86
- package/src/tools/task.d.ts.map +0 -1
- package/src/tools/task.js +0 -406
- package/src/tools/task.js.map +0 -1
- package/src/tools/usage.d.ts +0 -60
- package/src/tools/usage.d.ts.map +0 -1
- package/src/tools/usage.js +0 -174
- package/src/tools/usage.js.map +0 -1
- package/src/types/agent.d.ts +0 -2
- package/src/types/agent.d.ts.map +0 -1
- package/src/types/agent.js +0 -3
- package/src/types/agent.js.map +0 -1
- package/src/types/execution.d.ts +0 -2
- package/src/types/execution.d.ts.map +0 -1
- package/src/types/execution.js +0 -3
- package/src/types/execution.js.map +0 -1
- package/src/types/index.d.ts +0 -2
- package/src/types/index.d.ts.map +0 -1
- package/src/types/index.js +0 -2
- package/src/types/index.js.map +0 -1
- package/src/types/mcp.d.ts +0 -2
- package/src/types/mcp.d.ts.map +0 -1
- package/src/types/mcp.js +0 -3
- package/src/types/mcp.js.map +0 -1
- package/src/types/message.d.ts +0 -2
- package/src/types/message.d.ts.map +0 -1
- package/src/types/message.js +0 -3
- package/src/types/message.js.map +0 -1
- package/src/types/session.d.ts +0 -2
- package/src/types/session.d.ts.map +0 -1
- package/src/types/session.js +0 -3
- package/src/types/session.js.map +0 -1
- package/src/types/task.d.ts +0 -2
- package/src/types/task.d.ts.map +0 -1
- package/src/types/task.js +0 -3
- package/src/types/task.js.map +0 -1
- package/src/utils/ids.d.ts +0 -2
- package/src/utils/ids.d.ts.map +0 -1
- package/src/utils/ids.js +0 -5
- package/src/utils/ids.js.map +0 -1
- package/src/utils/logger.d.ts +0 -2
- package/src/utils/logger.d.ts.map +0 -1
- package/src/utils/logger.js +0 -5
- package/src/utils/logger.js.map +0 -1
- package/src/utils/timestamps.d.ts +0 -2
- package/src/utils/timestamps.d.ts.map +0 -1
- package/src/utils/timestamps.js +0 -4
- package/src/utils/timestamps.js.map +0 -1
- package/src/validation/agent.d.ts +0 -400
- package/src/validation/agent.d.ts.map +0 -1
- package/src/validation/agent.js +0 -251
- package/src/validation/agent.js.map +0 -1
- package/src/validation/agents.d.ts +0 -2
- package/src/validation/agents.d.ts.map +0 -1
- package/src/validation/agents.js +0 -3
- package/src/validation/agents.js.map +0 -1
- package/src/validation/errors.d.ts +0 -32
- package/src/validation/errors.d.ts.map +0 -1
- package/src/validation/errors.js +0 -42
- package/src/validation/errors.js.map +0 -1
- package/src/validation/execution.d.ts +0 -86
- package/src/validation/execution.d.ts.map +0 -1
- package/src/validation/execution.js +0 -28
- package/src/validation/execution.js.map +0 -1
- package/src/validation/index.d.ts +0 -9
- package/src/validation/index.d.ts.map +0 -1
- package/src/validation/index.js +0 -9
- package/src/validation/index.js.map +0 -1
- package/src/validation/mcp.d.ts +0 -42
- package/src/validation/mcp.d.ts.map +0 -1
- package/src/validation/mcp.js +0 -28
- package/src/validation/mcp.js.map +0 -1
- package/src/validation/message.d.ts +0 -43
- package/src/validation/message.d.ts.map +0 -1
- package/src/validation/message.js +0 -23
- package/src/validation/message.js.map +0 -1
- package/src/validation/session.d.ts +0 -49
- package/src/validation/session.d.ts.map +0 -1
- package/src/validation/session.js +0 -34
- package/src/validation/session.js.map +0 -1
- package/src/validation/task.d.ts +0 -146
- package/src/validation/task.d.ts.map +0 -1
- package/src/validation/task.js +0 -95
- package/src/validation/task.js.map +0 -1
- package/src/validation/tasks.d.ts +0 -2
- package/src/validation/tasks.d.ts.map +0 -1
- package/src/validation/tasks.js +0 -3
- package/src/validation/tasks.js.map +0 -1
- package/src/validation/usage.d.ts +0 -89
- package/src/validation/usage.d.ts.map +0 -1
- package/src/validation/usage.js +0 -98
- 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
|
package/src/tools/task.js.map
DELETED
|
@@ -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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"}
|
package/src/tools/usage.d.ts
DELETED
|
@@ -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
|
package/src/tools/usage.d.ts.map
DELETED
|
@@ -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"}
|
package/src/tools/usage.js
DELETED
|
@@ -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
|