@agimon-ai/doompi-task 0.0.1-alpha.76 → 0.0.1-alpha.77
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/dist/extensions/mcp.cjs +1866 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.cts +5 -0
- package/dist/extensions/mcp.d.cts.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +1836 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/tasks.server.cjs +2 -2
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/tasks.server.cjs.map +1 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/tasks.server.mjs +1 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/command/_lib/tasks.server.mjs.map +1 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.cjs +2 -104
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.cjs.map +1 -1
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.mjs +2 -101
- package/dist/src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.mjs.map +1 -1
- package/dist/src/services/taskTool/index.cjs +106 -0
- package/dist/src/services/taskTool/index.cjs.map +1 -0
- package/dist/src/services/taskTool/index.mjs +105 -0
- package/dist/src/services/taskTool/index.mjs.map +1 -0
- package/package.json +15 -7
|
@@ -1,107 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { applyTaskMutation, isCommittingOp } from "../../../../../../services/reducer/index.mjs";
|
|
3
|
-
import { buildAssignmentResult, buildTextResult, buildToolResult, formatAssignmentResults } from "../../../../../../services/taskResult/index.mjs";
|
|
1
|
+
import { createHeadlessTaskTool } from "../../../../../../services/taskTool/index.mjs";
|
|
4
2
|
import { defineServerTool } from "@agimon-ai/doompi-core/extension-file";
|
|
5
|
-
import { Check } from "typebox/value";
|
|
6
3
|
//#region src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.ts
|
|
7
|
-
function output(value) {
|
|
8
|
-
if (typeof value === "object" && value !== null && "content" in value) return value;
|
|
9
|
-
return {
|
|
10
|
-
content: [{
|
|
11
|
-
type: "text",
|
|
12
|
-
text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
|
|
13
|
-
}],
|
|
14
|
-
details: value
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
function failure(error) {
|
|
18
|
-
return {
|
|
19
|
-
content: [{
|
|
20
|
-
type: "text",
|
|
21
|
-
text: error instanceof Error ? error.message : String(error)
|
|
22
|
-
}],
|
|
23
|
-
isError: true
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
async function reducerAction(store, action, params, maxTasks) {
|
|
27
|
-
const { document, value } = await store.mutate((current) => {
|
|
28
|
-
const result = applyTaskMutation(current, action, params, void 0, maxTasks);
|
|
29
|
-
return {
|
|
30
|
-
...isCommittingOp(result.op) ? { document: result.document } : {},
|
|
31
|
-
value: result
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
if (value.op.kind === "error") throw new Error(value.op.message);
|
|
35
|
-
return buildToolResult(action, params, document, value.op);
|
|
36
|
-
}
|
|
37
|
-
async function assignmentBatch(manager, assignments, signal) {
|
|
38
|
-
const result = [];
|
|
39
|
-
for (const [index, assignment] of assignments.entries()) try {
|
|
40
|
-
const outcome = await manager.assign(assignment.id, {
|
|
41
|
-
agent: assignment.agent,
|
|
42
|
-
inlineAgent: assignment.inlineAgent,
|
|
43
|
-
instructions: assignment.instructions,
|
|
44
|
-
relevantFiles: assignment.relevantFiles,
|
|
45
|
-
priorFindings: assignment.priorFindings,
|
|
46
|
-
model: assignment.model,
|
|
47
|
-
...assignment.context === "fork" || assignment.context === "fresh" ? { context: assignment.context } : {},
|
|
48
|
-
signal
|
|
49
|
-
});
|
|
50
|
-
result.push({
|
|
51
|
-
index,
|
|
52
|
-
id: assignment.id,
|
|
53
|
-
agent: assignment.agent,
|
|
54
|
-
...outcome
|
|
55
|
-
});
|
|
56
|
-
} catch (error) {
|
|
57
|
-
result.push({
|
|
58
|
-
index,
|
|
59
|
-
id: assignment.id,
|
|
60
|
-
agent: assignment.agent,
|
|
61
|
-
ok: false,
|
|
62
|
-
message: String(error)
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
|
-
function createHeadlessTaskTool(store, manager, maxTasks) {
|
|
68
|
-
return {
|
|
69
|
-
name: "task",
|
|
70
|
-
label: "Task",
|
|
71
|
-
description: "Maintain a persistent task graph and delegate ready tasks to background agents.",
|
|
72
|
-
parameters: TaskParamsSchema,
|
|
73
|
-
promptSnippet: "Track complex work persistently and delegate ready tasks",
|
|
74
|
-
executionMode: "serial",
|
|
75
|
-
async execute(_toolCallId, rawParams, signal, onUpdate) {
|
|
76
|
-
if (!Check(TaskParamsSchema, rawParams)) return failure("Invalid task parameters.");
|
|
77
|
-
const params = rawParams;
|
|
78
|
-
try {
|
|
79
|
-
if (params.action === "assign") {
|
|
80
|
-
if (!params.assignments?.length) throw new Error("assign requires a non-empty assignments[] array");
|
|
81
|
-
onUpdate?.(output(`Delegating ${params.assignments.length} task${params.assignments.length === 1 ? "" : "s"}...`));
|
|
82
|
-
const items = await assignmentBatch(manager, params.assignments, signal);
|
|
83
|
-
const assigned = items.filter((item) => item.ok).map((item) => item.id);
|
|
84
|
-
const text = formatAssignmentResults(items);
|
|
85
|
-
if (assigned.length === 0) throw new Error(text);
|
|
86
|
-
return buildAssignmentResult(params, store.snapshot, text, {
|
|
87
|
-
assigned,
|
|
88
|
-
failed: items.length - assigned.length
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (params.action === "cancel") {
|
|
92
|
-
const outcome = await manager.cancel(params.id ?? NaN);
|
|
93
|
-
if (!outcome.ok) throw new Error(outcome.message);
|
|
94
|
-
return buildTextResult("cancel", params, store.snapshot, outcome.message);
|
|
95
|
-
}
|
|
96
|
-
return reducerAction(store, params.action, params, maxTasks);
|
|
97
|
-
} catch (error) {
|
|
98
|
-
return failure(error);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
4
|
var task_server_default = defineServerTool((context) => createHeadlessTaskTool(context.root.store, context.root.manager, context.root.maxTasks));
|
|
104
5
|
//#endregion
|
|
105
|
-
export {
|
|
6
|
+
export { task_server_default as default };
|
|
106
7
|
|
|
107
8
|
//# sourceMappingURL=task.server.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.server.mjs","names":[],"sources":["../../../../../../../../src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.ts"],"sourcesContent":["import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extension-file';\nimport type {
|
|
1
|
+
{"version":3,"file":"task.server.mjs","names":[],"sources":["../../../../../../../../src/extensions/workspaces/sessions/(backend)/tool/_lib/task.server.ts"],"sourcesContent":["import { defineServerTool, type WithRoot } from '@agimon-ai/doompi-core/extension-file';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/server-facet';\n\nimport { createHeadlessTaskTool } from '../../../../../../services/taskTool';\nimport type { TaskServerScope } from '../../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<DoomServerPluginContext, TaskServerScope>) =>\n createHeadlessTaskTool(context.root.store, context.root.manager, context.root.maxTasks),\n);\n"],"mappings":";;;AAMA,IAAA,sBAAe,kBAAkB,YAC/B,uBAAuB,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,QAAQ,KAAK,QAAQ,CACxF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const require_task = require("../../schemas/task.cjs");
|
|
2
|
+
const require_index = require("../reducer/index.cjs");
|
|
3
|
+
const require_index$1 = require("../taskResult/index.cjs");
|
|
4
|
+
let typebox_value = require("typebox/value");
|
|
5
|
+
//#region src/services/taskTool/index.ts
|
|
6
|
+
function output(value) {
|
|
7
|
+
if (typeof value === "object" && value !== null && "content" in value) return value;
|
|
8
|
+
return {
|
|
9
|
+
content: [{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
|
|
12
|
+
}],
|
|
13
|
+
details: value
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function failure(error) {
|
|
17
|
+
return {
|
|
18
|
+
content: [{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: error instanceof Error ? error.message : String(error)
|
|
21
|
+
}],
|
|
22
|
+
isError: true
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async function reducerAction(store, action, params, maxTasks) {
|
|
26
|
+
const { document, value } = await store.mutate((current) => {
|
|
27
|
+
const result = require_index.applyTaskMutation(current, action, params, void 0, maxTasks);
|
|
28
|
+
return {
|
|
29
|
+
...require_index.isCommittingOp(result.op) ? { document: result.document } : {},
|
|
30
|
+
value: result
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
if (value.op.kind === "error") throw new Error(value.op.message);
|
|
34
|
+
return require_index$1.buildToolResult(action, params, document, value.op);
|
|
35
|
+
}
|
|
36
|
+
async function assignmentBatch(manager, assignments, signal) {
|
|
37
|
+
const result = [];
|
|
38
|
+
for (const [index, assignment] of assignments.entries()) try {
|
|
39
|
+
const outcome = await manager.assign(assignment.id, {
|
|
40
|
+
agent: assignment.agent,
|
|
41
|
+
inlineAgent: assignment.inlineAgent,
|
|
42
|
+
instructions: assignment.instructions,
|
|
43
|
+
relevantFiles: assignment.relevantFiles,
|
|
44
|
+
priorFindings: assignment.priorFindings,
|
|
45
|
+
model: assignment.model,
|
|
46
|
+
...assignment.context === "fork" || assignment.context === "fresh" ? { context: assignment.context } : {},
|
|
47
|
+
signal
|
|
48
|
+
});
|
|
49
|
+
result.push({
|
|
50
|
+
index,
|
|
51
|
+
id: assignment.id,
|
|
52
|
+
agent: assignment.agent,
|
|
53
|
+
...outcome
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
result.push({
|
|
57
|
+
index,
|
|
58
|
+
id: assignment.id,
|
|
59
|
+
agent: assignment.agent,
|
|
60
|
+
ok: false,
|
|
61
|
+
message: String(error)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
function createHeadlessTaskTool(store, manager, maxTasks) {
|
|
67
|
+
return {
|
|
68
|
+
name: "task",
|
|
69
|
+
label: "Task",
|
|
70
|
+
description: "Maintain a persistent task graph and delegate ready tasks to background agents.",
|
|
71
|
+
parameters: require_task.TaskParamsSchema,
|
|
72
|
+
promptSnippet: "Track complex work persistently and delegate ready tasks",
|
|
73
|
+
executionMode: "serial",
|
|
74
|
+
async execute(_toolCallId, rawParams, signal, onUpdate) {
|
|
75
|
+
if (!(0, typebox_value.Check)(require_task.TaskParamsSchema, rawParams)) return failure("Invalid task parameters.");
|
|
76
|
+
const params = rawParams;
|
|
77
|
+
try {
|
|
78
|
+
if (params.action === "assign") {
|
|
79
|
+
if (!params.assignments?.length) throw new Error("assign requires a non-empty assignments[] array");
|
|
80
|
+
onUpdate?.(output(`Delegating ${params.assignments.length} task${params.assignments.length === 1 ? "" : "s"}...`));
|
|
81
|
+
const items = await assignmentBatch(manager, params.assignments, signal);
|
|
82
|
+
const assigned = items.filter((item) => item.ok).map((item) => item.id);
|
|
83
|
+
const text = require_index$1.formatAssignmentResults(items);
|
|
84
|
+
if (assigned.length === 0) throw new Error(text);
|
|
85
|
+
return require_index$1.buildAssignmentResult(params, store.snapshot, text, {
|
|
86
|
+
assigned,
|
|
87
|
+
failed: items.length - assigned.length
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (params.action === "cancel") {
|
|
91
|
+
const outcome = await manager.cancel(params.id ?? NaN);
|
|
92
|
+
if (!outcome.ok) throw new Error(outcome.message);
|
|
93
|
+
return require_index$1.buildTextResult("cancel", params, store.snapshot, outcome.message);
|
|
94
|
+
}
|
|
95
|
+
return reducerAction(store, params.action, params, maxTasks);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return failure(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
exports.createHeadlessTaskTool = createHeadlessTaskTool;
|
|
104
|
+
exports.reducerAction = reducerAction;
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["applyTaskMutation","isCommittingOp","buildToolResult","TaskParamsSchema","Check","formatAssignmentResults","buildAssignmentResult","buildTextResult"],"sources":["../../../../src/services/taskTool/index.ts"],"sourcesContent":["import type { DoomHeadlessTool, DoomHeadlessToolResult } from '@agimon-ai/doompi-core/headless';\nimport { Check } from 'typebox/value';\n\nimport type { TaskMutationParams } from '../../models/task';\nimport { TaskParamsSchema, type TaskParams, type TaskAssignmentParams } from '../../schemas/task';\nimport type { DelegationManager } from '../delegation';\nimport { applyTaskMutation, isCommittingOp, type ReducerAction } from '../reducer';\nimport { buildAssignmentResult, buildTextResult, buildToolResult, formatAssignmentResults } from '../taskResult';\nimport type { TaskStore } from '../taskStore';\n\nfunction output(value: unknown): DoomHeadlessToolResult {\n if (typeof value === 'object' && value !== null && 'content' in value) return value as DoomHeadlessToolResult;\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return { content: [{ type: 'text', text }], details: value };\n}\n\nfunction failure(error: unknown): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: error instanceof Error ? error.message : String(error) }], isError: true };\n}\n\nexport async function reducerAction(\n store: TaskStore,\n action: ReducerAction,\n params: TaskMutationParams,\n maxTasks: number,\n): Promise<DoomHeadlessToolResult> {\n const { document, value } = await store.mutate((current) => {\n const result = applyTaskMutation(current, action, params, undefined, maxTasks);\n return { ...(isCommittingOp(result.op) ? { document: result.document } : {}), value: result };\n });\n if (value.op.kind === 'error') throw new Error(value.op.message);\n return buildToolResult(action, params, document, value.op);\n}\n\ninterface AssignmentItemResult {\n index: number;\n id: number;\n agent: string;\n ok: boolean;\n message: string;\n}\n\nasync function assignmentBatch(\n manager: DelegationManager,\n assignments: readonly TaskAssignmentParams[],\n signal?: AbortSignal,\n): Promise<AssignmentItemResult[]> {\n const result: AssignmentItemResult[] = [];\n for (const [index, assignment] of assignments.entries()) {\n try {\n const outcome = await manager.assign(assignment.id, {\n agent: assignment.agent,\n inlineAgent: assignment.inlineAgent,\n instructions: assignment.instructions,\n relevantFiles: assignment.relevantFiles,\n priorFindings: assignment.priorFindings,\n model: assignment.model,\n ...(assignment.context === 'fork' || assignment.context === 'fresh' ? { context: assignment.context } : {}),\n signal,\n });\n result.push({ index, id: assignment.id, agent: assignment.agent, ...outcome });\n } catch (error) {\n result.push({ index, id: assignment.id, agent: assignment.agent, ok: false, message: String(error) });\n }\n }\n return result;\n}\n\nexport function createHeadlessTaskTool(\n store: TaskStore,\n manager: DelegationManager,\n maxTasks: number,\n): DoomHeadlessTool<typeof TaskParamsSchema> {\n return {\n name: 'task',\n label: 'Task',\n description: 'Maintain a persistent task graph and delegate ready tasks to background agents.',\n parameters: TaskParamsSchema,\n promptSnippet: 'Track complex work persistently and delegate ready tasks',\n executionMode: 'serial',\n async execute(_toolCallId, rawParams, signal, onUpdate) {\n if (!Check(TaskParamsSchema, rawParams)) return failure('Invalid task parameters.');\n const params = rawParams as TaskParams;\n try {\n if (params.action === 'assign') {\n if (!params.assignments?.length) throw new Error('assign requires a non-empty assignments[] array');\n onUpdate?.(\n output(`Delegating ${params.assignments.length} task${params.assignments.length === 1 ? '' : 's'}...`),\n );\n const items = await assignmentBatch(manager, params.assignments, signal);\n const assigned = items.filter((item) => item.ok).map((item) => item.id);\n const text = formatAssignmentResults(items);\n if (assigned.length === 0) throw new Error(text);\n return buildAssignmentResult(params as TaskMutationParams, store.snapshot, text, {\n assigned,\n failed: items.length - assigned.length,\n });\n }\n if (params.action === 'cancel') {\n const outcome = await manager.cancel(params.id ?? Number.NaN);\n if (!outcome.ok) throw new Error(outcome.message);\n return buildTextResult('cancel', params as TaskMutationParams, store.snapshot, outcome.message);\n }\n return reducerAction(store, params.action as ReducerAction, params as TaskMutationParams, maxTasks);\n } catch (error) {\n return failure(error);\n }\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { TaskParamsSchema } from "../../schemas/task.mjs";
|
|
2
|
+
import { applyTaskMutation, isCommittingOp } from "../reducer/index.mjs";
|
|
3
|
+
import { buildAssignmentResult, buildTextResult, buildToolResult, formatAssignmentResults } from "../taskResult/index.mjs";
|
|
4
|
+
import { Check } from "typebox/value";
|
|
5
|
+
//#region src/services/taskTool/index.ts
|
|
6
|
+
function output(value) {
|
|
7
|
+
if (typeof value === "object" && value !== null && "content" in value) return value;
|
|
8
|
+
return {
|
|
9
|
+
content: [{
|
|
10
|
+
type: "text",
|
|
11
|
+
text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
|
|
12
|
+
}],
|
|
13
|
+
details: value
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function failure(error) {
|
|
17
|
+
return {
|
|
18
|
+
content: [{
|
|
19
|
+
type: "text",
|
|
20
|
+
text: error instanceof Error ? error.message : String(error)
|
|
21
|
+
}],
|
|
22
|
+
isError: true
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async function reducerAction(store, action, params, maxTasks) {
|
|
26
|
+
const { document, value } = await store.mutate((current) => {
|
|
27
|
+
const result = applyTaskMutation(current, action, params, void 0, maxTasks);
|
|
28
|
+
return {
|
|
29
|
+
...isCommittingOp(result.op) ? { document: result.document } : {},
|
|
30
|
+
value: result
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
if (value.op.kind === "error") throw new Error(value.op.message);
|
|
34
|
+
return buildToolResult(action, params, document, value.op);
|
|
35
|
+
}
|
|
36
|
+
async function assignmentBatch(manager, assignments, signal) {
|
|
37
|
+
const result = [];
|
|
38
|
+
for (const [index, assignment] of assignments.entries()) try {
|
|
39
|
+
const outcome = await manager.assign(assignment.id, {
|
|
40
|
+
agent: assignment.agent,
|
|
41
|
+
inlineAgent: assignment.inlineAgent,
|
|
42
|
+
instructions: assignment.instructions,
|
|
43
|
+
relevantFiles: assignment.relevantFiles,
|
|
44
|
+
priorFindings: assignment.priorFindings,
|
|
45
|
+
model: assignment.model,
|
|
46
|
+
...assignment.context === "fork" || assignment.context === "fresh" ? { context: assignment.context } : {},
|
|
47
|
+
signal
|
|
48
|
+
});
|
|
49
|
+
result.push({
|
|
50
|
+
index,
|
|
51
|
+
id: assignment.id,
|
|
52
|
+
agent: assignment.agent,
|
|
53
|
+
...outcome
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
result.push({
|
|
57
|
+
index,
|
|
58
|
+
id: assignment.id,
|
|
59
|
+
agent: assignment.agent,
|
|
60
|
+
ok: false,
|
|
61
|
+
message: String(error)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
function createHeadlessTaskTool(store, manager, maxTasks) {
|
|
67
|
+
return {
|
|
68
|
+
name: "task",
|
|
69
|
+
label: "Task",
|
|
70
|
+
description: "Maintain a persistent task graph and delegate ready tasks to background agents.",
|
|
71
|
+
parameters: TaskParamsSchema,
|
|
72
|
+
promptSnippet: "Track complex work persistently and delegate ready tasks",
|
|
73
|
+
executionMode: "serial",
|
|
74
|
+
async execute(_toolCallId, rawParams, signal, onUpdate) {
|
|
75
|
+
if (!Check(TaskParamsSchema, rawParams)) return failure("Invalid task parameters.");
|
|
76
|
+
const params = rawParams;
|
|
77
|
+
try {
|
|
78
|
+
if (params.action === "assign") {
|
|
79
|
+
if (!params.assignments?.length) throw new Error("assign requires a non-empty assignments[] array");
|
|
80
|
+
onUpdate?.(output(`Delegating ${params.assignments.length} task${params.assignments.length === 1 ? "" : "s"}...`));
|
|
81
|
+
const items = await assignmentBatch(manager, params.assignments, signal);
|
|
82
|
+
const assigned = items.filter((item) => item.ok).map((item) => item.id);
|
|
83
|
+
const text = formatAssignmentResults(items);
|
|
84
|
+
if (assigned.length === 0) throw new Error(text);
|
|
85
|
+
return buildAssignmentResult(params, store.snapshot, text, {
|
|
86
|
+
assigned,
|
|
87
|
+
failed: items.length - assigned.length
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (params.action === "cancel") {
|
|
91
|
+
const outcome = await manager.cancel(params.id ?? NaN);
|
|
92
|
+
if (!outcome.ok) throw new Error(outcome.message);
|
|
93
|
+
return buildTextResult("cancel", params, store.snapshot, outcome.message);
|
|
94
|
+
}
|
|
95
|
+
return reducerAction(store, params.action, params, maxTasks);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return failure(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { createHeadlessTaskTool, reducerAction };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/services/taskTool/index.ts"],"sourcesContent":["import type { DoomHeadlessTool, DoomHeadlessToolResult } from '@agimon-ai/doompi-core/headless';\nimport { Check } from 'typebox/value';\n\nimport type { TaskMutationParams } from '../../models/task';\nimport { TaskParamsSchema, type TaskParams, type TaskAssignmentParams } from '../../schemas/task';\nimport type { DelegationManager } from '../delegation';\nimport { applyTaskMutation, isCommittingOp, type ReducerAction } from '../reducer';\nimport { buildAssignmentResult, buildTextResult, buildToolResult, formatAssignmentResults } from '../taskResult';\nimport type { TaskStore } from '../taskStore';\n\nfunction output(value: unknown): DoomHeadlessToolResult {\n if (typeof value === 'object' && value !== null && 'content' in value) return value as DoomHeadlessToolResult;\n const text = typeof value === 'string' ? value : JSON.stringify(value, null, 2);\n return { content: [{ type: 'text', text }], details: value };\n}\n\nfunction failure(error: unknown): DoomHeadlessToolResult {\n return { content: [{ type: 'text', text: error instanceof Error ? error.message : String(error) }], isError: true };\n}\n\nexport async function reducerAction(\n store: TaskStore,\n action: ReducerAction,\n params: TaskMutationParams,\n maxTasks: number,\n): Promise<DoomHeadlessToolResult> {\n const { document, value } = await store.mutate((current) => {\n const result = applyTaskMutation(current, action, params, undefined, maxTasks);\n return { ...(isCommittingOp(result.op) ? { document: result.document } : {}), value: result };\n });\n if (value.op.kind === 'error') throw new Error(value.op.message);\n return buildToolResult(action, params, document, value.op);\n}\n\ninterface AssignmentItemResult {\n index: number;\n id: number;\n agent: string;\n ok: boolean;\n message: string;\n}\n\nasync function assignmentBatch(\n manager: DelegationManager,\n assignments: readonly TaskAssignmentParams[],\n signal?: AbortSignal,\n): Promise<AssignmentItemResult[]> {\n const result: AssignmentItemResult[] = [];\n for (const [index, assignment] of assignments.entries()) {\n try {\n const outcome = await manager.assign(assignment.id, {\n agent: assignment.agent,\n inlineAgent: assignment.inlineAgent,\n instructions: assignment.instructions,\n relevantFiles: assignment.relevantFiles,\n priorFindings: assignment.priorFindings,\n model: assignment.model,\n ...(assignment.context === 'fork' || assignment.context === 'fresh' ? { context: assignment.context } : {}),\n signal,\n });\n result.push({ index, id: assignment.id, agent: assignment.agent, ...outcome });\n } catch (error) {\n result.push({ index, id: assignment.id, agent: assignment.agent, ok: false, message: String(error) });\n }\n }\n return result;\n}\n\nexport function createHeadlessTaskTool(\n store: TaskStore,\n manager: DelegationManager,\n maxTasks: number,\n): DoomHeadlessTool<typeof TaskParamsSchema> {\n return {\n name: 'task',\n label: 'Task',\n description: 'Maintain a persistent task graph and delegate ready tasks to background agents.',\n parameters: TaskParamsSchema,\n promptSnippet: 'Track complex work persistently and delegate ready tasks',\n executionMode: 'serial',\n async execute(_toolCallId, rawParams, signal, onUpdate) {\n if (!Check(TaskParamsSchema, rawParams)) return failure('Invalid task parameters.');\n const params = rawParams as TaskParams;\n try {\n if (params.action === 'assign') {\n if (!params.assignments?.length) throw new Error('assign requires a non-empty assignments[] array');\n onUpdate?.(\n output(`Delegating ${params.assignments.length} task${params.assignments.length === 1 ? '' : 's'}...`),\n );\n const items = await assignmentBatch(manager, params.assignments, signal);\n const assigned = items.filter((item) => item.ok).map((item) => item.id);\n const text = formatAssignmentResults(items);\n if (assigned.length === 0) throw new Error(text);\n return buildAssignmentResult(params as TaskMutationParams, store.snapshot, text, {\n assigned,\n failed: items.length - assigned.length,\n });\n }\n if (params.action === 'cancel') {\n const outcome = await manager.cancel(params.id ?? Number.NaN);\n if (!outcome.ok) throw new Error(outcome.message);\n return buildTextResult('cancel', params as TaskMutationParams, store.snapshot, outcome.message);\n }\n return reducerAction(store, params.action as ReducerAction, params as TaskMutationParams, maxTasks);\n } catch (error) {\n return failure(error);\n }\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-task",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.77",
|
|
4
4
|
"description": "Persistent, dependency-aware task graphs and subagent delegation for Pi coding sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -160,15 +160,15 @@
|
|
|
160
160
|
"registry": "https://registry.npmjs.org/"
|
|
161
161
|
},
|
|
162
162
|
"dependencies": {
|
|
163
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
164
|
-
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.
|
|
165
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
166
|
-
"@agimon-ai/doompi-web-components": "0.0.1-alpha.
|
|
163
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.77",
|
|
164
|
+
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.74",
|
|
165
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.77",
|
|
166
|
+
"@agimon-ai/doompi-web-components": "0.0.1-alpha.35",
|
|
167
167
|
"@deepseek-ai/cordis": "4.0.2",
|
|
168
168
|
"typebox": "1.3.30"
|
|
169
169
|
},
|
|
170
170
|
"devDependencies": {
|
|
171
|
-
"@agimon-ai/doompi-build": "0.0.1-alpha.
|
|
171
|
+
"@agimon-ai/doompi-build": "0.0.1-alpha.6",
|
|
172
172
|
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
173
173
|
"@earendil-works/pi-tui": "0.85.1",
|
|
174
174
|
"@tanstack/react-store": "0.11.1",
|
|
@@ -197,6 +197,13 @@
|
|
|
197
197
|
"engines": {
|
|
198
198
|
"node": ">=22.19.0"
|
|
199
199
|
},
|
|
200
|
+
"doompiMcp": {
|
|
201
|
+
"entry": "./generated/mcp.ts",
|
|
202
|
+
"dist": "./dist/extensions/mcp.mjs",
|
|
203
|
+
"scopes": [
|
|
204
|
+
"session"
|
|
205
|
+
]
|
|
206
|
+
},
|
|
200
207
|
"doompiServer": {
|
|
201
208
|
"entry": "./generated/server.ts",
|
|
202
209
|
"dist": "./dist/extensions/server.mjs",
|
|
@@ -226,7 +233,8 @@
|
|
|
226
233
|
]
|
|
227
234
|
},
|
|
228
235
|
"scripts": {
|
|
229
|
-
"build": "tsdown",
|
|
236
|
+
"build": "tsdown && tsdown --config tsdown.mcp.config.ts",
|
|
237
|
+
"build:mcp": "tsdown --config tsdown.mcp.config.ts",
|
|
230
238
|
"test": "vitest --run",
|
|
231
239
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
|
|
232
240
|
"lint": "oxlint . && oxfmt . --check",
|